必读:每个计算机科学家都应该了解的浮点运算知识,大卫·戈德堡。
问题不在于精度。相反,问题是代表性问题之一。首先,让我们回顾一下浮点数用于表示实数。实数的数量是无限的。当然,对于整数也可以这样说。但这里的区别在于,在特定范围内,整数的数量是有限的,而实数的数量是无限的。确实如此最初由康托尔展示,任何有限的实数区间都包含不可数的实数值。
So it is clear that we cannot represent all real numbers on a finite machine. So, which numbers can we represent? Well, that depends on the data type. Delphi floating point data types use binary representation. The single (32 bit) and double (64 bit) types adhere to the IEEE-754 standard. The extended (80 bit) type is an Intel specific type. In binary floating point a representable number has the form k2n where k and n are integers. Note that I am not claiming that all numbers of this form are representable. That is not possible because there are an infinite quantity of such numbers. Rather my point is that all representable numbers are of this form.
可表示的二进制浮点数的一些示例包括:1、0.5、0.25、0.75、1.25、0.125、0.375。您的值 3.7 不能表示为二进制浮点值。
就您的代码而言,这意味着它没有执行您期望的操作。您希望与值 3.7 进行比较。但相反,您正在与最接近的精确表示值 3.7 进行比较。作为实现细节的问题,这个最接近的精确可表示值是在扩展精度的情况下的。这就是为什么使用扩展的版本看起来符合您的预期。但是,不要认为这意味着您的变量x
等于3.7。事实上,它等于最接近的可表示扩展精度值 3.7。
罗布·肯尼迪的最有用的网站可以向您显示与特定数字最接近的可表示值。在 3.7 的情况下,这些是:
3.7 = + 3.70000 00000 00000 00004 33680 86899 42017 73602 98112 03479 76684 57031 25
3.7 = + 3.70000 00000 00000 17763 56839 40025 04646 77810 66894 53125
3.7 = + 3.70000 00476 83715 82031 25
这些按扩展、双、单的顺序呈现。换句话说,这些是变量的值x
, d
and s
分别。
如果您查看这些值,并将它们与最接近的扩展值 3.7 进行比较,您就会明白为什么您的程序会产生这样的输出。这里的单精度值和双精度值都大于扩展值。这就是你的程序告诉你的。
我不想就如何比较浮点值提出任何笼统的建议。做到这一点的最佳方法始终非常关键地取决于具体问题。无法给出有用的笼统建议。