Реальный против Плавающей Точки против Денег - PullRequest
19 голосов
/ 07 ноября 2008

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

Ответы [ 4 ]

45 голосов
/ 07 ноября 2008

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

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

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

12 голосов
/ 07 ноября 2008

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

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

5 голосов
/ 07 ноября 2008

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

1 голос
/ 07 ноября 2008

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...