хранение денежных сумм в MySQL - PullRequest
61 голосов
/ 12 февраля 2010

Я хочу сохранить 3.50 в таблицу MySQL. У меня есть поплавок, в котором я храню его, но он хранится как 3.5, а не 3.50. Как получить конечный ноль?

Ответы [ 7 ]

94 голосов
/ 12 февраля 2010

Не храните денежные значения как плавающие, используйте тип DECIMAL или NUMERIC:

Документация для числовых типов MySQL

РЕДАКТИРОВАТЬ и уточнения:

Значения с плавающей точкой уязвимы к ошибкам округления, если они имеют ограниченную точность, поэтому, если вам все равно, что вы получите только 9,99 вместо 10,00, вы должны использовать DECIMAL / NUMERIC, поскольку они являются числами с фиксированной точкой, у которых нет таких проблем.

36 голосов
/ 12 февраля 2010

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

Попробуйте вместо этого использовать DECIMAL (10,2).

19 голосов
/ 12 февраля 2010

Действительно ли имеет значение, если он хранится как 3,5, 3,50 или даже 3,500?

Что действительно важно, так это то, как оно отображается после получения из базы данных.

Или я что-то здесь упускаю?

Также не используйте число с плавающей запятой, используйте десятичное число. Float имеет всевозможные проблемы округления и не очень большой.

17 голосов
/ 12 февраля 2010

Для хранения значений вы можете использовать поле DECIMAL (10,2) , затем вы можете использовать функцию FORMAT :

SELECT FORMAT(`price`, 2) FROM `table` WHERE 1 = 1
5 голосов
/ 12 февраля 2010

Если вы используете типы DECIMAL или NUMERIC, вы можете объявить их как, например, DECIMAL (18, 2), которые будут иметь 2 десятичных знака, даже если они равны 0. В зависимости от ожидаемых больших значений, вы можете изменить значение первого параметр.

5 голосов
/ 12 февраля 2010

Почему вы хотите сохранить «3,50» в вашей базе данных? 3.5 == 3.50 == 3.5000, что касается базы данных.

Ваше представление и форматирование цифр / дат / и т. Д. Должно быть сделано в приложении, а не в базе данных.

0 голосов
/ 25 июня 2017

Двоичный код не может точно представлять числа с плавающей запятой только с ограниченным числом битов. Это не столько потеря данных, сколько ошибки преобразования. Вот руководство с примерами

Вы можете увидеть это в действии в своем браузере, убедитесь в этом фрагменте кода. <script> var floatSum = 0; // add 0.1 to floatSum 10 times for (var i=0; i<10; i++) { floatSum += 0.1; } // if the repetative adding was correct, the floatSum should be equal to 1 var expectedSum = 10*0.1; // 1 // you can see that floatSum does not equal 1 because of floating point error document.write(expectedSum + " == " + floatSum + " = " + (expectedSum==floatSum) + "<br />"); // --- using integers instead --- // Assume the example above is adding £0.10 ten times to make £1.00 // With integers, we will use store money in pence (100 pence (also written 100p) in £1) var intSum = 0; // add 0.1 to floatSum 10 times for (var i=0; i<10; i++) { intSum += 10; } // if the repetative adding was correct, the floatSum should be equal to 1 var expectedSum = 10*10; // 100 // you can see that floatSum does not equal 1 because of floating point error document.write(expectedSum + " == " + intSum + " = " + (expectedSum==intSum) + "<br />"); document.write("To display as &pound; instead of pence, we can divide by 100 (presentation only) : &pound;" + intSum/100 + "<br />"); </script>

...