Вопрос по php, mysql – Неправильная десятичная точность MySQL и PHP

0

24151.40 - 31891.10 = -7739.699999999997

I grab these two numbers from a MySQL table with the type as decimal(14,2) 24151.40 31891.10 It is saved exactly as stated above and it echos exactly like that in PHP. But the minute I subtract the second value from the first value, I get a number -7739.699999999997 instead of -7,739.7. Why the extra precision? And where is it coming from?

Ваш Ответ

3   ответа
4

статья, которую я написал для Authorize.Net:

Один плюс один равняется двум, верно? Как насчет 0,2 плюс 1,4 раза 10? Это равно 16, верно? Нет, если вы занимаетесь математикой с помощью PHP (или большинства других языков программирования):

echo floor((0.2 + 1.4) * 10); // Should be 16. But it's 15!

Это связано с тем, как числа с плавающей запятой обрабатываются внутри. Они представлены с фиксированным числом десятичных разрядов и могут привести к тому, что числа будут складываться не совсем так, как вы ожидаете. Внутренне наш пример .2 плюс 1.4 умножить на 10 примерно на 15.9999999998 или около того. Этот вид математики хорош при работе с числами, которые не должны быть точными, как проценты. Но при работе с деньгами точность имеет значение, так как ни копейки, ни доллара, пропущенного здесь или там, складываются быстро, и никому не нравится быть в выигрыше в пропущенных деньгах.

The BC Math Solution

К счастью, PHP предлагаетДо н.э Математическое расширение что "для математики произвольной точности" PHP предлагает Бинарный калькулятор, который поддерживает числа любого размера и точности, представленные в виде строк. & quot; Другими словами, вы можете сделать точную математику с денежными значениями, используя это расширение.BC Math расширение содержит функциюs, которые позволяют вам выполнять наиболее распространенные операции с точностью, включаяприбавление, вычитание, умножение, а такжеделение.

A Better Example

Здесь тот же пример, что и выше, но с использованием функции bcadd (), чтобы сделать математику за нас. Требуется три параметра. Первые два - это значения, которые мы хотим добавить, а третье - это количество десятичных разрядов, к которым мы хотим быть точными. Поскольку мы работаем с деньгами, мы установим точность в два десятичных знака.

echo floor(bcadd('0.2', '1.4', 2) * 10); // It's 16 like we would expect it to be.
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded Anderson
Error: User Rate Limit Exceeded Anderson
Error: User Rate Limit Exceeded Anderson
1

что с научной точки зрения относится к 1.FRACTAL * 2 ^ экспоненциальной мощности. Поскольку префикс равен 1, технически отсутствует такая вещь, как ноль, и ближайшим значением, которое можно получить до 0, является 1,0 * 2 ^ -127, что составляет 0,000000 [127 0s] 00001

Округляя ваш ответ с определенной точностью, коэффициент округления даст вам более точный ответ

http://dev.mysql.com/doc/refman/5.0/en/mathematical-functions.html#function_round

1

как в MySQL, он использует числа с плавающей запятой; а поплавки печально известны своей неточностью.

Чтобы вылечить это, посмотрите вnumber_formatНапример:

echo number_format(24151.40 - 31891.10, 2, '.', '');

Для более точной обработки чисел вы также можете посмотреть математические расширения PHP:

http://www.php.net/manual/en/refs.math.php

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded Anderson
Error: User Rate Limit Exceeded Anderson

Похожие вопросы