2016-04-11 3 views
0

Я пытаюсь вычитать числа с плавающей запятой в python. Я значениявычитание с плавающей запятой в python

a = 1460356156116843.000000, b = 2301.93138123

Когда я пытаюсь напечатать a-b, это в результате на значение 1460356156114541.000000 вопреки фактическому значению 1460356156114541.06861877.

Каковы ограничения в python при выполнении арифметики с плавающей запятой. Есть ли способ в python, через который я могу получить фактический результат этого вычитания?

+2

Похоже, что python делает целочисленное вычитание или анализирует результат на целое число. Можете ли вы точно показать, как вы назначаете значения и как вы вычисляете результат? Просто скопируйте код связанного кода, пожалуйста. – FallenAngel

+1

См. Также http://sopython.com/canon/87/why-is-this-particular-floating-point-math-operation-not-giving-the-correct-answ/ – tripleee

+1

Номера с плавающей запятой в основном представляют значимые цифры , поэтому вы не можете отслеживать небольшие различия между большими числами. Поскольку ваш 'a' составляет 16 цифр, не осталось« комнаты », чтобы также представить дробную разницу.В каком контексте вы участвуете в том, что вам нужно отслеживать различия, которые настолько малы по сравнению с участвующими цифрами? – BrenBarn

ответ

3

Python имеет те же ограничения для арифметики с плавающей запятой, что и все другие языки. Вы можете использовать Decimal, чтобы получить точный результат:

from decimal import Decimal 

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

print a - b # 1460356156114541.06861877 
1

Python использует IEEE 754 doubles для своих плаваний. Поэтому вы должны лечить что-либо после 15 значимых цифр или как научная фантастика. И это только для недавно инициализированного номера. Когда вы начинаете делать операции с поплавками, вы можете потерять больше точности, особенно делая сложение или вычитание между числами, которые значительно различаются по абсолютной величине.

OTOH, делая вычитание между числами очень близко друг к другу по величине может привести к catastrophic cancellation.

Если вы будете осторожны, вы можете уменьшить влияние этих проблем, но вам необходимо знать, как работает арифметика с плавающей запятой, и корректные данные.

В качестве альтернативы вы можете работать с библиотекой, которая обеспечивает более высокую точность, например, десятичный модуль Python. Вам все равно нужно позаботиться о том, чтобы избежать катастрофической отмены и других проблем, которые приводят к потере значимости, но по крайней мере у вас есть более значимые цифры.

Модуль Decimal предоставляет простые арифметические операции. Если вам нужны передовые математические функции, такие как триггерные и экспоненциальные функции, взгляните на отличный сторонний модуль произвольной точности математики mpmath. Он может обрабатывать сложные числа, решать уравнения и выполнять некоторые операции исчисления.

0

Использование десятичной точки удобно. Но ради демонстрации важности сохранения значительных цифр позвольте мне привести этот пример.

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

Итак, для вышеуказанного случая вы можете выполнить вычисление в два этапа.

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

Так что ответ будет добавлением двух. Но если вы это сделаете, вы потеряете все плавающие цифры. 64-разрядный не достаточно большой, чтобы хранить все цифры.

Смежные вопросы