Fehler in C++ Code?

2 Antworten

Es scheint, dass das Problem bei der Verwendung der Variablentypen liegt. Der Datentyp "long double" kann manchmal zu unerwarteten Rundungsfehlern führen. Eine bessere Möglichkeit wäre, den Datentyp "double" zu verwenden, der in der Regel ausreichend präzise ist.

Hier ist eine mögliche Lösung:

std::string formatBytes(uint64_t bytes) {
    const char* suffixes[] = {"B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"};
    const int numSuffixes = 9;


    int power = 0;
    double size = static_cast<double>(bytes);


    while (size >= 1024 && power < numSuffixes) {
        size /= 1024;
        ++power;
    }


    std::ostringstream oss;
    oss.precision(2);
    oss << std::fixed << size << ' ' << suffixes[power];
    return oss.str();
}


Hier wird der Datentyp "double" anstelle von "long double" verwendet, und der Wert von "bytes" wird mit "static_cast<double>(bytes)" in den Datentyp "double" umgewandelt. Dadurch sollten die Rundungsfehler behoben werden.

LukasZander 
Fragesteller
 10.05.2023, 23:32

Vielen Dank. Zuvor war der Code tatsächlich mit double geschrieben, aber ich dache mit long double komme ich vielleicht weiter. Jedenfalls klappte es leider auch mit double nicht.

Aus irgendeinem Grund bekomme ich 16.00 EB, wenn ich eine 6 oder 7 Gb große Dateigröße per stat::st_size an formatBytes übergebe...

0
OmniosX  11.05.2023, 00:15
@LukasZander

Hmm vielleicht mal die Bibliothek vergrößern, kann sein dass das Ergebnis immer noch abgeschnitten wird weil 16 Exabytes echt ne Nummer ist.

Wie ist es damit?

#include <iostream>
#include <boost/format.hpp>


std::string formatBytes(long long bytes) {
    const int base = 1024;
    static const char *suffixes[] = {"B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"};


    if (bytes == 0) return "0B";


    const int exp = std::min((int)(log(bytes) / log(base)), 8);
    const double size = bytes / pow(base, exp);


    boost::format fmt("%.2f%s");
    fmt % size % suffixes[exp];


    return fmt.str();
}


int main() {
    const long long size = 7000000000;
    std::cout << formatBytes(size) << std::endl; // output: 6.51GB
    return 0;
}


0

Ich gehe auch davon aus, daß der long double das Problem ist.

Verzichte mal auf die Nachkommastellen und mache das mit Deinem 64 Bit unint und schau mal, ob dann die korrekte Endung erzeugt wird.

LukasZander 
Fragesteller
 11.05.2023, 00:05

Nein, da kommt dasselbe dabei heraus..

0
KarlRanseierIII  11.05.2023, 00:11
@LukasZander

Nur mal am Rande, it 2^64 kannst du eh nur 16 EB maximal darstellen. Warum allerdings schon bei etwa 6 GB ein Fehler auftritt ist mir direkt nicht ersichtlich.

1
LukasZander 
Fragesteller
 11.05.2023, 00:25
@KarlRanseierIII

Ah, also das 16 EB ein Maximum ist könnte ein Hinweis sein, was mein Code falsch macht. Und dabei bis ans Limit..Dann rechnet der Code unabsichtlich weiter..Ich habe leider auch keine Idee warum

0