Frage

Ich habe eine long double konstant, dass ich entweder als const oder nicht-const setze. Es ist länger (40 Stellen) als die Präzision eines long double auf meiner Test-Workstation (19 Stellen).

Wenn ich es ausdrucken, es wird nicht mehr auf 19 Stellen genau angezeigt, aber bei 16.

Hier ist der Code Ich teste:

#include <iostream>
#include <iomanip>
#include <limits>
#include <cstdio>

int main ()
{
    const long double constLog2 = 0.6931471805599453094172321214581765680755;
    long double log2 = 0.6931471805599453094172321214581765680755;    

    std::cout << std::numeric_limits<long double>::digits10 + 1 << std::endl;
    std::cout << "const via cout: " << std::setprecision(19) << constLog2 << std::endl;
    std::cout << "non-const via cout: " << std::setprecision(19) << log2 << std::endl;
    std::fprintf(stdout, "const via printf: %.19Lf\n", constLog2);
    std::fprintf(stdout, "non-const via printf: %.19Lf\n", log2);

    return 0;
}

Übersetzen:

$ g++ -Wall precisionTest.cpp

Ausgabe:

$ ./a.out
19
const via cout: 0.6931471805599452862
non-const via cout: 0.6931471805599452862
const via printf: 0.6931471805599452862
non-const via printf: 0.6931471805599452862

Ich würde 0.6931471805599453094 erwarten, sondern 0.6931471805599452862 erhalten.

Gibt es einen Grund, dass die 19-stelliger Genauigkeit zu 16 Stellen geschnitten werden?

Hier ist meine Umwelt:

$ gcc --version
i686-apple-darwin9-g++-4.0.1 (GCC) 4.0.1 (Apple Inc. build 5490)

Ich sehe das gleiche Problem mit anderen Versionen von gcc, z.

$ gcc --version
g++ (GCC) 3.4.6 20060404 (Red Hat 3.4.6-10)
Blick in NTL oder anderen Bibliotheken

ich kann, aber ich bin gespannt, was dies verursacht. Vielen Dank für Ihre Einsicht.

War es hilfreich?

Lösung

ich diese Ausgabe:

19
const via cout: 0.6931471805599453094
non-const via cout: 0.6931471805599453094
const via printf: 0.6931471805599453094
non-const via printf: 0.6931471805599453094

Aber ich bin lange Doppel Literale statt Doppel Literale mit:

const long double constLog2 = 0.6931471805599453094172321214581765680755L;
long double log2 = 0.6931471805599453094172321214581765680755L;    

Andere Tipps

Es gibt einige subtilen Fragen im Zusammenhang mit Hardware-Plattformen und kompilieren Optionen, die von Interesse sein könnten:

Diese '-m‘Optionen sind definiert für die i386 und x86-64-Familie von Computern:

  

-m96bit-long-double

     

-m128bit-long-double

     

Diese Schalter steuern die Größe der langen Doppel Typ.   Die i386 Application Binary Interface   die Größe spezifiziert 96 Bits zu sein, so   -m96bit-long-double ist die Standardeinstellung in 32-Bit-Modus. moderne Architekturen   (Pentium und neuere) würde es vorziehen, lange   doppelt auf einen 8 oder 16 ausgerichtet werden,   Byte-Grenze. In Arrays oder Strukturen   mit dem ABI konforme, würde dies nicht   möglich sein. So spezifiziert ein   -m128bit-long-Doppel wird long double zu einer Grenze 16-Byte-ausgerichtet, indem   Klotzen des long double mit einem   zusätzliche 32-Bit-Null.

     

In dem x86-64-Compiler,   -m128bit-long-double ist die Standardeinstellung als ABI, dass lange spezifiziert   Doppel ist auf 16-Byte-ausgerichtet werden,   Grenze.

     

Beachten Sie, dass keine dieser Optionen   ermöglichen jede zusätzliche Präzision über die   x87-Standard von 80 Bits für eine lange   doppelt.

     

Achtung: Wenn Sie die Standardeinstellung überschreiben   Wert für Ihr Ziel ABI, die   Strukturen und Anordnungen, enthaltend lange   Doppel Variablen ihre ändern   Größe sowie Funktionsaufruf   Konvention für die Funktion nehmen lange   Doppel wird modifiziert werden. daher sie   nicht binär kompatibel mit   Arrays oder Strukturen in Code kompiliert   ohne diesen Schalter.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top