2016-04-11 21 views
0

Ich versuche, zu Gleitkommazahlen in Python zu subtrahieren. Ich habe WertFließkomma-Subtraktion in Python

a = 1460356156116843.000000, b = 2301.93138123

Wenn ich versuche, a-b zu drucken, es 1460356156114541.06861877 den Wert 1460356156114541.000000 im Gegensatz zu dem tatsächlichen Wert ist resultiert.

Was sind die Einschränkungen in Python bei der Gleitkommaarithmetik? Gibt es einen Weg in Python, durch den ich das tatsächliche Ergebnis dieser Subtraktion erhalten kann?

+2

Es sieht so aus, als ob Python ganzzahlige Subtraktion oder Parsing des Ergebnisses zu Integer macht. Können Sie genau zeigen, wie Sie die Werte zuweisen und wie Sie das Ergebnis berechnen? Kopieren Sie einfach den zugehörigen Codeblock bitte. – FallenAngel

+1

Siehe auch http://sopthon.com/canon/87/why-is-is-this-particular-floating-point-math-operation-not-giving-the-correct-answ/ – tripleee

+1

Fließkommazahlen stellen im Wesentlichen signifikante Stellen dar , so können Sie kleine Unterschiede zwischen großen Zahlen nicht verfolgen. Da Ihr 'a' 16 Ziffern lang ist, gibt es keinen" Raum "mehr, um auch den Bruchteilunterschied darzustellen.In welchem ​​Kontext müssen Sie Unterschiede, die im Verhältnis zu den beteiligten Zahlen so gering sind, im Auge behalten? – BrenBarn

Antwort

3

Python hat die gleichen Einschränkungen für Gleitkommaarithmetik wie alle anderen Sprachen. Sie können Decimal verwenden, um die genauen Ergebnisse zu erhalten:

from decimal import Decimal 

a = Decimal('1460356156116843.000000') 
b = Decimal('2301.93138123') 

print a - b # 1460356156114541.06861877 
1

Python verwendet IEEE 754 doubles für seinen Schwimmer. Sie sollten also alles nach 15 signifikanten Zahlen oder so als Science-Fiction behandeln. Und das nur für eine frisch initialisierte Nummer. Wenn Sie Operationen mit Gleitkommazahlen ausführen, können Sie mehr Genauigkeit verlieren, insbesondere wenn Sie Addition oder Subtraktion zwischen Zahlen vornehmen, die sich in der absoluten Größe signifikant unterscheiden.

OTOH, Subtraktion zwischen Zahlen sehr nahe beieinander in der Größenordnung kann zu catastrophic cancellation führen.

Wenn Sie vorsichtig sind, können Sie die Auswirkungen dieser Probleme zu reduzieren, aber Sie tun brauchen ein gutes Verständnis der Fließkomma-Arithmetik funktioniert, und wohlerzogene Daten.

Alternativ können Sie mit einer Bibliothek arbeiten, die eine höhere Genauigkeit bietet, z. B. Pythons Dezimal-Modul. Sie müssen immer noch darauf achten, eine katastrophale Löschung und die anderen Probleme zu vermeiden, die zu einem Bedeutungsverlust führen, aber zumindest haben Sie wichtigere Ziffern zum Spielen.

Das Decimal-Modul bietet nur grundlegende arithmetische Operationen. Wenn Sie erweiterte mathematische Funktionen wie trigonometrische Funktionen und Exponentialfunktionen benötigen, werfen Sie einen Blick auf das exzellente mathematische Modul mpmath. Es kann komplexe Zahlen verarbeiten, Gleichungen lösen und einige Rechenoperationen durchführen.

0

Verwenden von Dezimal ist praktisch. Aber um die Wichtigkeit der Beibehaltung signifikanter Ziffern zu demonstrieren, möchte ich dieses Beispiel anführen.

import sys 
print(sys.maxsize) 
9223372036854775807 # for 64 bit machine, the max integer number. But it can grow as needed. 

Also für den obigen Fall können Sie die Berechnung in zwei Schritten tun.

1460356156116842 - 2301 = 1460356156114541 # all integer digits preserved 
1 - .93138123 = 0.06861877 # all significant float digits preserved. 

Also wäre die Antwort die beiden hinzufügen. Aber wenn Sie das tun, werden Sie alle Gleitziffern verlieren. Das 64bit ist nicht groß genug, um alle Ziffern zu behalten.