诸如“为什么 0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1 = 0.8 不是?“让我想到...
...最好让编译器警告浮点常量,它舍入到二进制浮点类型中最接近的可表示形式(例如 0.1 和 0.8 以基数 2 浮点舍入,否则它们需要无限量的空间来存储无限数量的数字)。
我查找了 gcc 警告,到目前为止没有发现任何用于此目的的警告(-Wall
, -Wextra
, -Wfloat-equal
, -Wconversion
, -Wcoercion
(不支持或仅支持 C?),-Wtraditional
(仅限 C)似乎没有做我想做的事)。
我在 Microsoft Visual C++ 编译器中也没有发现这样的警告。
我是否错过了隐藏或很少使用的选项?
有没有任何编译器有这种警告?
EDIT:此警告可能有助于教育目的,并可作为浮点新手的提醒。
编译器没有任何技术原因无法发出此类警告。然而,它们只对学生(在开始认真使用浮点运算之前应该学习浮点运算如何工作)和那些在浮点方面做得很好的人有用。不幸的是,大多数浮点工作都很粗糙。人们把数字扔到计算机上,不太关心计算机是如何工作的,他们接受得到的任何结果。
默认情况下必须关闭该警告才能支持大量现有浮点代码。如果它可用,我会在 Mac OS X 数学库中为我的代码打开它。当然,库中有些地方我们依赖于浮点值的每一位,例如我们使用扩展精度算术的地方,并且值是跨多个浮点对象表示的(例如,我们会有一个一个对象的高位为 1/π,另一个对象的 1/π 减去第一个对象,第三个对象的 1/π 减去前两个对象,得到大约 150 位的 1/π)。一些此类值在源文本中以十六进制浮点表示,以避免编译器转换十进制数字时出现任何问题,并且我们可以轻松转换任何剩余数字以避免新的编译器警告。
然而,我怀疑我们能否说服编译器开发人员相信有足够多的人会使用此警告,或者它会捕获足够多的错误以使其值得花费时间。考虑 libm 的情况。假设我们通常为所有常量写出精确的数字,但有一次写了一些其他数字。这个警告会发现错误吗?嗯,有什么bug吗?无论如何,数字很可能会准确地转换为我们想要的值。当在打开此警告的情况下编写代码时,我们可能会考虑如何执行浮点计算,并且我们编写的值是适合我们目的的值。例如,它可能是我们计算的某个极小极大多项式的系数,并且无论是近似以十进制表示还是转换为某种可精确表示的十六进制浮点数字,该系数都尽可能好。
因此,此警告很少会捕获错误。也许它会捕获我们错误输入数字的情况,意外地将额外的数字插入到十六进制浮点数字中,导致它超出了可表示的有效数。但这种情况很少见。在大多数情况下,我们使用的数字要么简单又短,要么是从计算它们的软件中复制和粘贴的。在某些情况下,我们会手动输入特殊值,例如0x1.ffffffffffffffp0。当额外的“f”插入该数字时发出警告可能会在编译期间捕获错误,但该错误几乎肯定会在测试中很快被捕获,因为它极大地改变了特殊值。
因此,这样的编译器警告几乎没有什么用处:很少有人会使用它,而且对于使用它的人来说,它捕获的错误也很少。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)