Проблема точности с плавающей точкой в ​​PHP и MySQL для хранения случайных десятичных значений

Я хочу хранить случайные десятичные значения в моей базе данных MySQL и отображать их в моем приложении PHP. Позвольте мне объяснить, что я имею в виду под случайными десятичными значениями. Числа в большинстве случаев являются целыми числами, как целое число. Например, 160 или 170 и т. Д. Но иногда мне нужно сохранять такие значения, как 98,6.

Сначала я использовал DECIMAL(4,1) тип данных в базе данных, и я обнаружил, что я всегда получаю такие числа: 160.0, 170.0 и 98.6 и т. д. Итак, я изменил его на FLOAT, В моей локальной среде я вижу числа 160, 170, 98.6 и т. Д. Как в приложении PHP, так и в phpMyAdmin. Но в моей производственной среде я вижу такие цифры, как 160, 170, 98.6 и т. Д. На phpMyAdmin. Но в PHP-приложении я вижу такие числа, как 160, 170, 98.599998474121 и т. Д.

Теперь мне нужно решить, стоит ли переключаться обратно на decimal или продолжайте использовать float, И в любом случае, мне нужно найти решение для преобразования чисел в формат, подобный этому: 160, 170 и 98.6 и т. Д.

Как вы думаете, что лучше для этого: decimal или же float? Каков наилучший способ преобразовать числа в целые числа, если дробная часть числа равна нулю (при использовании decimal)? Каков наилучший способ преобразования значений с плавающей запятой, например 98,599998474121, в 98,6?

Преобразование чисел в целые числа, если дробная часть числа равна нулю:

<?php
if (fmod($number, 1) == 0) {
$number = intval($number)
}

Есть ли лучший способ?

2

Решение

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

// the casts are there just for the demonstration, you probably don't need them
$number = "170";
echo round((float)$number, 1); // gives 170
$number = "98.6";
echo round((float)$number, 1); // gives 98.6

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

0

Другие решения

Я тоже сталкивался с этой ошибкой. (Прочитай это http://www.leaseweblabs.com/2013/06/the-php-floating-point-precision-is-wrong-by-default/ )

Это ошибка, связанная с PHP.

Если вы точно знаете, что ваша дробная часть имеет максимум одну цифру, и вы встречаете больше, вы знаете, что вам нужно заново обработать число

Вы можете получить точность следующим образом:

function precision($num) {
return strlen(substr($num, strpos($num, '.')+1));
}
0

По вопросам рекламы [email protected]