Реальный против плавающей точки против денег

Почему, когда я сохраняю значение 40.54 в SQL Server в столбце типа Real, он возвращает мне значение, которое больше похоже на 40.53999878999 вместо 40.54? Я видел это несколько раз, но никогда не понял, почему это происходит. Кто-нибудь еще испытал эту проблему, и если это так ее вызвало?

Ответ 1

Посмотрите Что каждый компьютерный ученый должен знать о арифметике с плавающей точкой.

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

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

Ответ 2

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

Для денег лучше хранить число центов как целое или использовать десятичный тип. Например, Decimal (8,2) хранит 8 цифр, включая 2 десятичных знака (xxxxxx.xx), т.е. До цента.

Ответ 4

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

Некоторые системы, с другой стороны, хранят дробные числа в десятичных (десятичные и числовые типы данных SQL Server и, например, тип данных Oracle Number), а затем их внутреннее представление является точным для любого числа, которое является степенью из 10. Но тогда цифры, которые не являются степенями 10, не могут быть представлены точно.