Я нашел некоторое решение для проблема с плавающей запятой в PHP:
Настройка php.ini precision = 14
342349.23 - 341765.07 = 584.15999999992 // floating point problem
Настройка php.ini, скажем precision = 8
342349.23 - 341765.07 = 584.16 // voila!
Демо: http://codepad.org/r7o086sS
Насколько это плохо?
1. Могу ли я полагаться на это решение, если мне нужны только точные двухзначные вычисления (деньги)?
2. Если вы не можете дать мне ясный пример, когда эти решения не удались?
Изменить: 3. Какое значение php.ini.precision соответствует лучшим двум цифрам, расчету денег
- Обратите внимание: я не могу использовать целочисленные вычисления (float * 100 = центы), это слишком поздно для этого.
- Я не буду работать над цифрами выше 10 ^ 6
- Мне не нужно сравнивать числа
UPDATE
@Baba ответ хороший, но он использовал precision=20
, precision=6
в своих тестах... Итак, я не уверен, что это сработает или нет.
Обратите внимание на следующее:
Скажем precision = 8
, и только то, что я делаю, это дополнение +
и вычитание -
A + B = C
A - B = C
Вопрос 1: Будет ли прерывание с точностью до чисел между 0..999999.99, где A и B - число с десятичными знаками? Если да, пожалуйста, предоставьте мне пример.
Простой тест выполнит задание:
// if it fails what if I use 9,10,11 ???
// **how to find when it fails??? **
ini_set('precision', 8);
for($a=0;$a<999999.99;$a+=0.01) {
for($b=0;$b<999999.99;$b+=0.01) {
// mind I don't need to test comparision (round($a-$b,2) == ($a-$b))
echo ($a + $b).','.($a - $b)." vs ";
echo round($a + $b, 2).','.round($a - $b, 2)."\n";
}
}
но, очевидно, 99999999 * 2
слишком большая работа, поэтому я не могу запустить этот тест
Вопрос 2: Как оценивать/вычислять, когда обход ошибки точности не выполняется? Без таких сумасшедших тестов? Есть ли какой-либо математический *, прямой ответ для него? Как рассчитать будет неудачно или нет?
* Мне не нужно знать, как работают вычисления с плавающей запятой, но когда обходной путь выходит из строя, если вы знаете точность и диапазон A и B
Обратите внимание на Я действительно знаю, что центы и bcmath - лучшее решение. Но все же я не уверен, что обходной путь не удастся или не для подстановки и добавления