【发布时间】:2010-11-08 12:13:20
【问题描述】:
已经向 SO 发布了几个关于浮点表示的问题。例如,十进制数 0.1 没有精确的二进制表示,因此使用 == 运算符将其与另一个浮点数进行比较是很危险的。我了解浮点表示背后的原理。
我不明白的是,为什么从数学角度来看,小数点右边的数字比左边的数字更“特殊”?
例如,数字 61.0 具有精确的二进制表示,因为任何数字的整数部分始终是精确的。但数字 6.10 并不准确。我所做的只是将小数点移动一位,然后我突然从 Exactopia 转到了 Inexactville。从数学上讲,这两个数字之间应该没有本质区别——它们只是数字。
相比之下,如果我将小数点向另一个方向移动一位以产生数字 610,我仍然在 Exactopia。我可以继续朝那个方向前进(6100、610000000、610000000000000),它们仍然是准确的、准确的、准确的。但是一旦小数超过某个阈值,数字就不再准确了。
发生了什么事?
编辑:澄清一下,我想远离关于行业标准表示的讨论,例如 IEEE,并坚持我认为是数学上“纯”的方式。以 10 为底,位置值为:
... 1000 100 10 1 1/10 1/100 ...
在二进制中,它们是:
... 8 4 2 1 1/2 1/4 1/8 ...
对这些数字也没有任意限制。位置向左和向右无限增加。
【问题讨论】:
-
您可能会发现这有助于准确了解浮点数中发生的事情:Anatomy of a floating point number。
-
在二进制中,数字 3 表示为 2¹+2°=2+1。好,易于。现在,看看1/3。使用 2 的负幂,你会如何表示它?稍作实验,您会发现 1/3 等于无限序列 2^-2 + 2^-4 + 2^-6 + 2^-8 + ... 的总和,即。用二进制精确表示并不容易。
-
Jon Skeet 很好地回答了你体内的问题。缺少的一件事是您实际上提出了两个不同的问题。标题问题是“为什么十进制数不能用二进制精确表示?”答案是,他们可以。在您的标题和正文之间,您将“二进制”的概念和“浮点表示”的概念混为一谈。浮点是一种以固定数量的二进制数字表示十进制数字的方法,但会以精度为代价。二进制只是计数的不同基数,可以表示任何十进制数,给定无限位数。
-
有几个系统具有精确的十进制表示。它的工作原理与您描述的非常相似。 SQL 十进制类型就是一个例子。 LISP 语言内置了它。有几个商业和开源库用于使用精确的十进制计算。只是没有硬件支持,而且大多数语言和硬件都实现了 IEEE 标准,以 32 位或 64 位表示无限数量的数字。
-
这个问题似乎离题了,因为它是关于数学的(即使它是与编程相关的数学)并且在Mathematics上会更好
标签: math floating-point