Дополнение числами с плавающей точкой в ​​JavaScript и PHP и постоянство - PullRequest
0 голосов
/ 29 августа 2018

Поскольку я уверен, что многие из них испытали это, у меня возникла небольшая проблема с математикой с плавающей запятой - я исправил эту проблему в JavaScript , хотя пока кажется в порядке PHP Я хотел убедиться, что на него можно положиться, поскольку он немного отличается от версии JS.

JavaScript:

var item = 25.00;
var postage = 24.99;

((item + postage) * 100) // 4998.999999999999

Очевидно, я не хочу этого, я хочу 49.99, поэтому я изменяю это на:

((item + postage) * 100).toFixed(0) // 4999 (string)

Тогда для хорошей меры я изменил это на:

provideFloat((book_price + shipping_cost) * 100).toFixed(0)) // 4999 (float)

function provideFloat(num) {
    return parseFloat(num.replace(/,/g, ''));
}

Теперь мне нужно проверить против этого числа на стороне PHP, чтобы увидеть, совпадают ли они, поэтому я попробовал (например):

PHP:

$item = 25.00;
$postage = 24.99;

echo ((item + $postage) * 100); // 4999

Так что, как вы можете видеть, результат отличается от JavaScript - могу ли я полагаться на то, что это "правильно" для сравнения и не заканчивается чем-то вроде 4998.999999999999?

Ради интереса я попытался применить аналогичную технику, которую я применил к JavaScript с аналогичным подходом , который JS использует в своей функции toFixed, с:

$number = (($item + $postage) * 100);
$expo = pow(10,0);
$number = intval($number * $expo) / $expo;

echo $number; // 4998

... и я получаю 4998, тогда как JS получил 4999 - так что мне следует придерживаться того, что на самом деле дает 4999 результат? На это можно положиться?

.. или вам нужно идти на такие крайности?

$res = (($item + $postage) * 100);
$res = (float) number_format($res, 0, '.','');
echo $res; // 4999

Мой вариант использования: мне нужно преобразовать числа с плавающей запятой (в долларах) в центы, а затем сравнить их со стороны клиента и до конца сервера.

1 Ответ

0 голосов
/ 29 августа 2018

Простой ответ: Нет. Вы не можете полагаться на точность с плавающей запятой в PHP или любом другом языке. Хотя это может работать в этом примере, будут случаи, когда оно не будет совпадать.

Если требуется точность, либо используйте целые числа для математики, либо используйте bcadd () со строками.

Если достаточно близко, все в порядке, вы должны уйти с помощью round (). number_format () нежелателен для сравнения, только для форматирования (см. разделитель тысяч).

...