不精确浮点常量的警告 [英] Warning for inexact floating-point constants

查看:37
本文介绍了不精确浮点常量的警告的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

诸如为什么不是 0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1 = 0.8?"之类的问题让我想到...

Questions like "Why isn't 0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1 = 0.8?" got me thinking that...

... 让编译器警告它四舍五入到二进制浮点类型中最接近的可表示的浮点常量可能会很好(例如 0.1 和 0.8 在基数 2 浮点数中四舍五入,否则他们将需要无限量的空间来存储无限数量的数字).

... It would probably be nice to have the compiler warn about the floating-point constants that it rounds to the nearest representable in the binary floating-point type (e.g. 0.1 and 0.8 are rounded in radix-2 floating-point, otherwise they'd need an infinite amount of space to store the infinite number of digits).

我已经查找了 gcc 警告,但到目前为止没有发现任何用于此目的的警告(-Wall-Wextra-Wfloat-equal-Wconversion-Wcoercion(不受支持或仅 C 语言?)、-Wtraditional(仅 C 语言)似乎没有做我所做的想要).

I've looked up gcc warnings and so far found none for this purpose (-Wall, -Wextra, -Wfloat-equal, -Wconversion, -Wcoercion (unsupported or C only?), -Wtraditional (C only) don't appear to be doing what I want).

我也没有在 Microsoft Visual C++ 编译器中发现这样的警告.

I haven't found such a warning in Microsoft Visual C++ compiler either.

我是否遗漏了一个隐藏的或很少使用的选项?

Am I missing a hidden or rarely-used option?

是否有任何编译器有这种警告?

Is there any compiler at all that has this kind of warning?

编辑:此警告可用于教育目的,并提醒那些刚接触浮点数的人.

EDIT: This warning could be useful for educational purposes and serve as a reminder to those new to floating-point.

推荐答案

编译器无法发出此类警告没有技术原因.然而,它们只对学生(在开始认真研究浮点算术之前应该教他们如何工作)和对浮点数做非常好的工作的人有用.不幸的是,大多数浮点运算都很粗糙.人们向计算机扔数字,而不太关心计算机的工作原理,他们接受他们得到的任何结果.

There is no technical reason the compiler could not issue such warnings. However, they would be useful only for students (who ought to be taught how floating-point arithmetic works before they start doing any serious work with it) and people who do very fine work with floating-point. Unfortunately, most floating-point work is rough; people throw numbers at the computer without much regard for how the computer works, and they accept whatever results they get.

默认情况下必须关闭警告以支持大量现有浮点代码.如果它可用,我会在 Mac OS X 数学库中为我的代码打开它.当然,库中有些地方我们依赖浮点值的每一位,例如我们使用扩展精度算术的地方,并且值在多个浮点对象中表示(例如,我们会有一个高位为 1/π 的对象,另一个对象为 1/π 减去第一个对象,第三个对象为 1/π 减去前两个对象,得到大约 150 位的 1/π).一些这样的值在源文本中以十六进制浮点数表示,以避免十进制数字的编译器转换出现任何问题,我们可以轻松地转换任何剩余的数字以避免新的编译器警告.

The warning would have to be off by default to support the bulk of existing floating-point code. Were it available, I would turn it on for my code in the Mac OS X math library. Certainly there are points in the library where we depend on every bit of the floating-point value, such as places where we use extended-precision arithmetic, and values are represented across more than one floating-point object (e.g., we would have one object with the high bits of 1/π, another object with 1/π minus the first object, and a third object with 1/π minus the first two objects, giving us about 150 bits of 1/π). Some such values are represented in hexadecimal floating-point in the source text, to avoid any issues with compiler conversion of decimal numerals, and we could readily convert any remaining numerals to avoid the new compiler warning.

然而,我怀疑我们能否说服编译器开发人员相信有足够多的人会使用这个警告,或者它会捕捉到足够多的错误,值得他们花时间.考虑 libm 的情况.假设我们通常为所有常数写出精确的数字,但有一次,写了一些其他数字.此警告会捕获错误吗?嗯,有什么错误?最有可能的是,无论如何,数字都被转换为我们想要的值.在编写启用此警告的代码时,我们可能会考虑如何执行浮点计算,我们编写的值是适合我们目的的值.例如,它可能是我们计算出的某个极大极小多项式的系数,并且无论是近似地以十进制表示还是转换为某些精确可表示的十六进制浮点数,该系数都将得到它的最佳结果.

However, I doubt we could convince the compiler developers that enough people would use this warning or that it would catch enough bugs to make it worth their time. Consider the case of libm. Suppose we generally wrote exact numerals for all constants but, on one occasion, wrote some other numeral. Would this warning catch a bug? Well, what bug is there? Most likely, the numeral is converted to exactly the value we wanted anyway. When writing code with this warning turned on, we are likely thinking about how the floating-point calculations will be performed, and the value we have written is one that is suitable for our purpose. E.g., it may be a coefficient of some minimax polynomial we calculated, and the coefficient is as good as it is going to get, whether represented approximately in decimal or converted to some exactly-representable hexadecimal floating-point numeral.

因此,此警告很少会捕获错误.也许它会抓住我们错误输入数字的情况,不小心在十六进制浮点数字中插入了一个额外的数字,导致它超出了可表示的有效数.但这很少见.在大多数情况下,我们使用的数字要么简单又简短,要么是从计算它们的软件中复制粘贴的.在某些情况下,我们会手动键入特殊值,例如 0x1.fffffffffffffp0.当一个额外的f"滑入该数字时发出警告可能会在编译期间捕获错误,但该错误几乎肯定会在测试中快速捕获,因为它会彻底改变特殊值.

So, this warning will rarely catch bugs. Perhaps it would catch an occasion where we mistyped a numeral, accidentally inserting an extra digit into a hexadecimal floating-point numeral, causing it to extend beyond the representable significand. But that is rare. In most cases, the numerals we use are either simple and short or are copied and pasted from software that has calculated them. On some occasions, we will hand-type special values, such as 0x1.fffffffffffffp0. A warning when an extra "f" slips into that numeral might catch a bug during compilation, but that error would almost certainly be caught quickly in testing, since it drastically alters the special value.

所以,这样的编译器警告没有什么用处:很少有人会使用它,而且它会为使用它的人捕获很少的错误.

So, such a compiler warning has little utility: Very few people will use it, and it will catch very few bugs for the people who do use it.

这篇关于不精确浮点常量的警告的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆