在没有 epsilon 的情况下使用浮点数总是有代码味道吗?
这个问题很简单。它与以下内容相关,但绝对不是骗局:
大多数未打补丁的 Tomcat Web 服务器都很脆弱,谁的错?
看到了惊人的数量浮点数可能会出错(包括但不限于不同体系结构上的不同结果、使用不正确时的错误结果、影响两种不同语言的两次拒绝服务崩溃等)我想知道一个非常简单的问题:
没有 epsilon 的浮点数总是代码气味或规范气味吗?
(也就是说:浮点数真的应该只用于科学计算和所有其余的应该使用固定位数的精度来完成?)
This question is very simple. It is related to but definitely not a dupe of:
Most unpatched Tomcat webservers are vulnerable, who's at fault?
Seen the amazing amount of things that can go wrong with floating-point numbers (including, but not limited to, different results on different architectures, wrong results when used incorrectly, two denial of services crashes affecting two different languages, etc.) I'm wondering a very simple question:
Are floating-point numbers used without an epsilon always a code-smell or a spec-smell?
(that is: should floating-point number really only ever be used for scientific computation and all the rest should be done using a fixed number of bits of precision?)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
不,它们绝对不总是代码味道。
事实上,在我的工作中(低级高性能库),带有容差的浮点比较是一种代码味道:它们表明程序员要么不理解浮点,要么不完全理解他们正在实现的算法的数字,这敲响了很大的警钟,我应该非常非常仔细地阅读其余的代码。
这并不是说永远不应该使用它们。在很多情况下(甚至可能是大多数情况)这样做是正确的。只是说所有硬性规定都是愚蠢,包括这个。
对于您澄清的问题:“浮点数真的应该只用于科学计算,而其余的都应该使用固定位数的精度来完成吗?”
当然不是。这将是一个巨大的工程负担,而且启动效率极低。对于没有经验的程序员来说,使用整数算术(溢出、除法截断、越界数组访问等)就像使用浮点一样容易搬起石头砸自己的脚。浮点对于绝大多数程序员来说是一个巨大的便利。如果不是,就不会使用。
与所有事情一样,花时间了解您的工具,并使用正确的工具来完成工作。
No, they are absolutely not always a code smell.
In fact, in my line of work (low-level high-performance libraries), floating-point comparisons with a tolerance are a code smell: they indicate that the programmer either does not understand floating point, or does not fully understand the numerics of the algorithm that they are implementing, which sets off big warning bells that I should be reading over the rest of the code very, very closely.
That's not to say that they should never be used. There are lots of situations (maybe even most situations) where it's the right thing to do. It's only to say that all hard-and-fast rules are stupid, this one included.
To your clarified question: "should floating-point number really only ever be used for scientific computation and all the rest should be done using a fixed number of bits of precision?"
Of course not. That would be a monstrous engineering burden, and grossly inefficient to boot. It's just as easy for an inexperienced programmer to shoot himself in the foot with integer arithmetic (overflows, division-is-truncation, out-of-bounds array access, etc, etc) as it is with floating point. Floating-point is an enormous convenience for the vast majority of programmers; if it wasn't it wouldn't be used.
As with all things, take the time to learn about your tools, and use the right tool for the job.
有时确实不需要精确。游戏引擎始终使用浮点进行渲染。同样,您不会使用浮点数进行货币计算,但使用浮点数编写图形系统并不是问题。
当您合并两组不同的数据(一组不精确,一组精确(或更精确))时,问题就出现了。例如,游戏开发人员通常最终使用与渲染相同的坐标系作为世界坐标,然后,当世界变得巨大时,它们的单精度浮点数开始显示出严重的舍入误差。完整全局位置坐标的容差与 2D 局部区域到 3D 屏幕空间坐标系的容差不同。
sometimes there's really no need for precision. Game engines use floating points for rendering all the time. Likewise, you wouldn't do monetary computation with floats, but it's not a problem writing a graphing system with floats.
The problem comes when you conflate two different sets of data (one non-precise, one precise (or more precise)) For example, game developers often wind up using the same coordinate system for their world-coordinates as they do for the rendering, and then when the world gets huge, their single-precision floats start showing major rounding errors. The tolerance for a full global-location coordinate isn't the same as the tolerance in a 2D-local-area-to-3D-screen-space coordinate system.