为什么当我在SQL Server中将值为40.54的值保存到Real类型的列时,它会返回给我一个更像40.53999878999而不是40.54的值?我已经看过几次,但从来没有弄明白为什么会发生这种情况。还有其他人遇到过这个问题吗?如果有的话会导致这个问题吗?
答案 0 :(得分:45)
查看What Every Computer Scientist Should Know About Floating Point Arithmetic。
计算机中的浮点数不完全代表小数。相反,它们代表二进制分数。大多数小数都没有精确表示为二进制小数,因此有一些舍入。当这样的舍入二进制分数被转换回小数分数时,您将获得您描述的效果。
为了存储货币值,SQL数据库通常提供存储精确十进制数字的DECIMAL类型。这种格式对于计算机来说处理效率稍差,但是当你想避免十进制舍入错误时它非常有用。
答案 1 :(得分:12)
浮点数使用二进制分数,它们与十进制分数不完全对应。
为了钱,最好将分数存储为整数,或者使用十进制数字类型。例如,十进制(8,2)存储8位数,包括2位小数(xxxxxx.xx),即分数精度。
答案 2 :(得分:5)
简而言之,这几乎是因为三分之一不能用十进制来精确表达。有关详细信息,请查看David Goldberg的经典论文“What Every Computer Scientist Should Know About Floating-Point Arithmetic”。
答案 3 :(得分:1)
要添加说明,存储在计算机中的浮点数的行为与此处其他帖子的描述相同,因为如上所述,它以二进制格式存储。 这意味着除非它的值(值的尾数和指数分量)都是2的幂,并且不能准确表示。
另一方面,某些系统存储十进制小数(例如SQL Server十进制数和数字数据类型,以及Oracle数据类型),然后它们的内部表示对于任何一个幂的数字都是精确的然而,那些不是10的幂的数字无法准确表示。