20

为什么当我在 SQL Server 中将 40.54 的值保存到 Real 类型的列时,它返回给我的值更像 40.53999878999 而不是 40.54?我已经看过几次了,但从来没有弄清楚为什么会发生这种情况。有没有其他人遇到过这个问题,如果是这样导致它?

4

4 回答 4

46

看看每个计算机科学家应该知道的关于浮点运算的知识。

计算机中的浮点数不能精确地表示小数。相反,它们代表二进制分数。大多数小数没有作为二进制分数的精确表示,因此需要进行一些舍入。当这样一个四舍五入的二进制分数被转换回十进制分数时,你会得到你描述的效果。

为了存储货币值,SQL 数据库通常提供 DECIMAL 类型来存储精确的十进制数字。这种格式对计算机来说处理效率稍低,但当您想要避免小数舍入错误时,它非常有用。

于 2008-11-07T19:42:53.893 回答
13

浮点数使用二进制分数,它们不完全对应于十进制分数。

对于金钱,最好将美分数存储为整数,或使用十进制数类型。例如,Decimal(8,2) 存储 8 位数字,包括 2 位小数 (xxxxxx.xx),即精确到分。

于 2008-11-07T19:42:30.227 回答
6

简而言之,由于几乎相同的原因,三分之一不能精确地用十进制表示。有关详细信息,请查看 David Goldberg 的经典论文“ What Every Computer Scientist Should Know About Floating-Point Arithmetic ”。

于 2008-11-07T19:44:31.410 回答
1

澄清一下,存储在计算机中的浮点数的行为与此处其他帖子的描述一样,因为如上所述,它以二进制格式存储。这意味着除非它的值(值的尾数和指数分量)是 2 的幂,并且不能精确表示。

另一方面,一些系统以十进制存储小数(例如 SQL Server 十进制和数字数据类型,以及 Oracle 数字数据类型),因此它们的内部表示对于任何 10 的幂的数字都是精确的。但是,不是 10 的幂的数字不能精确表示。

于 2008-11-07T20:27:12.087 回答