2 Stimmen

Erhöhen Sie die Multi-Präzision von cpp_dec_float und vergleichen Sie nur bis zur gewünschten Genauigkeit.

Ich benutze die boost::multiprecision-Bibliothek für Dezimal-Gleitkommazahlen und möchte zwei Gleitkommazahlen mit der angegebenen Genauigkeit vergleichen.

Allerdings scheint cpp_dec_float die Zahl nicht nur auf die angegebene Genauigkeit zu vergleichen, sondern auch die Wachposten-Ziffern einzuschließen:

#include 

#include 
//#include 

typedef boost::multiprecision::number > flp_type;

int main(int argc, char* argv[])
{
    // 50 Dezimalstellen
    flp_type sqrt2("1.4142135623730950488016887242096980785696718753769");
    // Enthält berechnete Wachposten-Ziffern
    flp_type result(boost::multiprecision::sqrt(flp_type("2")));

    // Die 50 Dezimalstellen Präzision sind tatsächlich gleich
    std::cout << std::setprecision(50) << sqrt2 << std::endl;
    std::cout << std::setprecision(50) << result << std::endl;
    // Ich möchte, dass dies mit der angegebenen Präzision des Typs verglichen wird, nicht mit den Wachposten-Ziffern
    std::cout << (result==sqrt2) << std::endl;

    return 0;
}

Ausgabe:

1.4142135623730950488016887242096980785696718753769
1.4142135623730950488016887242096980785696718753769
0

Erwartet:

1.4142135623730950488016887242096980785696718753769
1.4142135623730950488016887242096980785696718753769
1

Siehe auf Coliru

Ich habe versucht, mit precision() zu "trunkieren", aber ohne Erfolg. Gibt es eine Möglichkeit, die beiden Zahlen zu vergleichen, ohne auf Epsilon-Vergleiche zurückzugreifen?

2voto

sehe Punkte 346808

Wenn Sie die Wachbits entfernen, beeinträchtigen Sie effektiv die Genauigkeit des Typs wie beabsichtigt.

Ein sicheres Mittel wäre die Verwendung der (De-)Serialisierung.

Also schlage ich vor

<a href="http://coliru.stacked-crooked.com/a/47cd5a600eff483e" rel="nofollow">Live bei Coliru</a>

// Entweder
std::cout << std::numeric_limits::epsilon() << "\n";
std::cout << (abs(result-sqrt2) < std::numeric_limits::epsilon()) << std::endl;

// Oder
result = flp_type { result.str(49, std::ios::fixed) };
std::cout << (result==sqrt2) << std::endl;

Beachten Sie, dass das Epsilon dort 1e-49 beträgt

Druckt

1.4142135623730950488016887242096980785696718753769
1.4142135623730950488016887242096980785696718753769
1e-49
1
1

Offensichtlich würde der Vergleich auf Basis von epsilon() effizienter erscheinen

0voto

Long Bu Punkte 513
bool ist_gleich = abs(ergebnis - sqrt2) < std::pow(10, -std::numeric_limits< flp_typ >::digits10 );

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X