2012-06-27 5 views
1

Для следующегоPHP, странный результат

echo 0.02-0.01-0.06+0.05; 

я получил результат

6.93889390391E-18 

Для этого один

echo -0.02+0.02; 

я получил результат

0 

Я хочу знать, почему у меня есть другой результат для тех, кто. Я предполагаю получить два результата 0.

+0

'эхо (0,06 + 0,05) - (0.02-0.01); '= 0,1 –

ответ

4

Вот так floating point numbers работа.

+0

Как предотвратить это? Потому что я хочу получить 0, но не другую ценность. –

+2

«предотвратить» - вы не можете, действительно. Но вы можете просто [округлить] (http://php.net/round) до «хорошего» номера. 'round (0.02-0.01-0.06 + 0.05,10)' даст вам '0'. Обратите внимание, что даже 'round' может испортить float, но это довольно редко. –

1

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

Представления с плавающей точкой представляют собой приближения с ограниченной точностью.

это не конкретная вещь, а компьютеры просто не могут представлять числа, как мы их концептуализируем.

+0

Этот конкретный случай может быть PHP-вещью в том, что схема представления с плавающей запятой PHP обрабатывает числа, которые в некоторой степени участвуют, но другие схемы могут улучшиться. Например, Perl, Python, Ruby и, несколько смешно, Wolfram Alpha (в своем препопе) дают тот же результат, что и PHP, но Pike дает 0. – chaos

0

Если вы обмениваете его на два или три десятичных знака, это исправит его для вас.

1

Когда вы пишете цифры «0,02» в исходном коде, компилятор или интерпретатор использует их с плавающей запятой. Наиболее распространенным форматом с плавающей запятой является двоичная с плавающей точкой IEEE 754 с одноточечной или двойной точностью.

Этот формат с плавающей запятой не может точно представлять большинство десятичных цифр. Например, так же, как десятичные числа не могут точно представлять 1/3 (это приблизительно 0,3333, но любая десятичная цифра конечной длины заканчивается где-то, поэтому она немного отличается от 1/3), двоичные числа, используемые в плавающей запятой, не могут представлять 1/10 точно (в двоичном, 1/10 - приблизительно .000110011001100110011).

Поэтому, когда вы пишете «0.02-0.01-0.06 + 0.05», компьютер не выполняет арифметику с точно такими числами. Он использует близкие приближения. Таким образом, результат, который вы получаете, близок.

Если вы хотите получить точный результат, вы должны либо изучить детали арифметики с плавающей запятой, чтобы вы могли создавать операции, которые позволяют избежать ошибок или для которых ошибка может быть исправлена, или вы должны использовать только целочисленную арифметику. Например, если вышеуказанные доллары суммы добавляются и вычитаются, вы можете вместо этого хранить суммы пенни и вычислять «2-1-6 + 5».

0

Привет просто для кого-то hiting эту проблему, вы можете использовать произвольные точности функции из библиотеки BCMath http://php.net/manual/en/ref.bc.php

echo 12606.69 + 3053.46 - 15660.15; 
1.8189894035459E-12 

и

echo bcadd((12606.69 + 3053.46),-15660.15); 
0 
Смежные вопросы