Was ist das Risiko von numerischen Instabilitäten bei der Zerlegung von Nennern?

8

Angenommen, ich möchte eine Zahl in viele teilen.

%Vor%

Da die Multiplikation schneller ist, ist die Versuchung, dies zu tun

%Vor%

1) Ist dies garantiert identische Antworten? Ich vermute nicht, aber eine Bestätigung wäre schön.

2) Wenn x extrem groß oder extrem klein ist, könnte dies zu einem erheblichen Genauigkeitsverlust führen. Gibt es eine Formel, die mir sagen wird, wie viel Genauigkeit ich opfern werde?

3) Vielleicht gibt es keine praktische Formel, aber können wir zumindest eine Faustregel für numerische Instabilitäten angeben? Hat es mit den Größen der Operanden oder dem Unterschied zwischen den Größen der Operanden zu tun?

    
spraff 02.02.2015, 14:04
quelle

4 Antworten

5

1) Nein, nicht garantiert identische Antworten zu produzieren. Selbst mit IEEE können feine Rundungseffekte zu einem Unterschied von 1 oder 2 ULP führen, wenn a/x oder% co_de verwendet wird %.

2) Wenn a*(1/x) extrem klein ist (das ist ein bisschen kleiner als x (minimale normalisierte positive Fließkommazahl) wie bei Unter-Normalen), ist DBL_MIN 1/x mit total Verlust der Präzision. Ein potentiell signifikanter Genauigkeitsverlust tritt auch dann auf, wenn das FP-Modell keine Sub-Normalen unterstützt Durch Testen von INF gegen die größte endliche Zahl x und die kleinste nicht-null |x| kann der Code feststellen, wann ein signifikanter Genauigkeitsverlust beginnt. Eine Formel würde wahrscheinlich von dem verwendeten FP-Modell und dem Exponenten von <= 1/DBL_MIN sowie den Grenzen des Modells abhängen. In diesem Bereich von binary64 unterscheidet sich der binäre Exponent von >= 1/DBL_MAX und x (oder x ) wäre die erste Größenordnung von verlorenen Bits.

3) In den oben besprochenen Bereichen treten erhebliche numerische Instabilitäten auf.

    
chux 02.02.2015, 15:46
quelle
2

Hier sind ein paar Gedanken mit unterstützenden Links:

1) - Gleiche Ergebnisse erzielen? Keine Garantien. Es gibt zu viele Beiträge zur Variabilität, alles vom uP-Design (erinnere dich an den Mathe-Coprozessor Designfehler des 486 DX Mathe-Coprozessors?) zur Compiler-Implementierung, wie ein Float im Hardware-Speicher abgelegt ist. ( Gute Diskussion dazu hier. )

2) - Formel? Ich bin mir einer nicht bewusst. Und was meinst du mit signifikantem Fehler? In jedem Fall können Sie Erwartungen an die Genauigkeit stellen, die Sie sehen werden:

  
  • Verständnis verschiedene Implementierungen von Gleitkommazahlen (Link vergleicht 2)
  •   
  • Welcher Variablentyp wird verwendet ( float , double , long double ). ( Unterschiede ) )
  •   
  • Welche Architektur bauen Sie auf?   32 Bit oder 64 Bit, andere?
  •   

Es gibt viele Diskussionen über Gleitkommafehler. Hier ist einer

3) Es gibt keine echten Faustregeln (wenn Sie nach Faustregel das einfach verstehen denken Sie daran, einfach anzuwenden, einfach zu verstehen) aber hier ist ein guter Versuch bei der Beantwortung dieser Frage bezüglich Gleitkommafehler

    
ryyker 02.02.2015 14:49
quelle
2

Da Sie mit ieee-754-Nummern arbeiten, würde ich sagen, dass Ihr Ansatz vollkommen akzeptabel ist. In ieee-754 x ist grob

  

mantisa * 2 Exponent

Wo Mantisa eine Zahl zwischen 1/2 und 1 ist.

Solange Sie nur Multiplikationen und Divisionen durchführen, haben Sie natürlich einen Genauigkeitsverlust, aber dieser Verlust ist unabhängig von der Größe von x (*) und bezieht sich nur auf die Genauigkeit des Floating-Typs verwendet (einzelne, doppelte Quad-Genauigkeit, dh float , double oder long double , je nach Compiler und Architektur).

(*) Das ist nur wahr, solange Sie keinen Überlauf des Unterlaufs haben, also etwa 10 38 für eine einfache Genauigkeit von 10 300 für doppelte Genauigkeit.

Referenzen: Seiten Fließkomma und IEEE Fließkomma auf Wikipedia

    
Serge Ballesta 02.02.2015 14:43
quelle
0

Meine 50 Cent dazu:

1) Nein, weiter unter Punkt 3 erklärt.

2) Ich kenne keine Formel, also werde ich diese hier einfach überspringen.

3) Die Faustregel, die ich kenne, besteht darin, zu versuchen, Operationen nur zwischen Operanden mit einer ähnlichen Größenordnung durchzuführen.

Praxisbeispiel:

Sie möchten die Zahl 63.000.000 durch 1.000.000 dividieren.

Wenn Sie den ersten Ansatz verwenden, werden Sie schließlich 63 * 10 ^ 6 bis 1 * 10 ^ 6 teilen, die sehr nahe beieinander liegen.

Wenn Sie jedoch den zweiten Ansatz verwenden möchten,

%Vor%

Produziert 10 ^ (- 6).

Nun wird die Multiplikation von 63 * 10 ^ 6 * 10 ^ (-6) zu signifikanten Präzisionsverlusten führen, da der Größenunterschied zwischen den beiden sehr groß ist. Die CPU wird versuchen, die Exponent + Bruchdarstellung der 10 ^ 6 Zahl zu verwenden, um die 10 ^ (- 6) Zahl darzustellen ...

Eine praktikable Alternative wäre, dass temp

wäre %Vor%

Und dann

%Vor%

Da die Magnitude näher ist, besteht eine geringere Wahrscheinlichkeit für einen Präzisionsverlust.

    
MichaelCMS 02.02.2015 14:19
quelle

Tags und Links