问题描述
在 F# 中.如何有效地比较几乎相等的浮点数?它也应该适用于非常大和非常小的值.我想先比较指数,然后比较有效数(尾数),同时忽略其 52 位的最后 4 位.这是一个好方法吗?如何获得浮点数的指数和有效数?
In F#. How to efficiently compare floats for equality that are almost equal? It should work for very large and very small values too. I am thinking of first comparing the Exponent and then the Significand (Mantissa) while ignoring the last 4 bits of the its 52 bits. Is that a good approach? How can I get the Exponent and Significand of a float?
推荐答案
F# float
只是 System.Double
的简写.既然如此,您可以使用 BitConverter.DoubleToInt64Bits 有效地(并且安全地!)将 F# float
值转换"为 int64
的方法;这很有用,因为它避免了分配 byte[]
,正如 John 在他的评论中提到的.您可以使用一些简单的按位运算从 int64
中获取指数和有效数.
An F# float
is just a shorthand for System.Double
. That being the case, you can use the BitConverter.DoubleToInt64Bits method to efficiently (and safely!) "cast" an F# float
value to int64
; this is useful because it avoids allocating a byte[]
, as John mentioned in his comment. You can get the exponent and significand from that int64
using some simple bitwise operations.
不过,正如约翰所说,您可能最好通过简单的检查来确定相对准确度.对于许多用例(例如,检查迭代求解器是否收敛于一个解决方案),它可能是最快的解决方案并且足够接近".如果您需要特定的准确度,请查看 NUnit 的代码——它有一些不错的 API,用于断言值在预期值的特定百分比或 ulps 数量内.
As John said though, you're probably better off with a simple check for relative accuracy. It's likely to be the fastest solution and "close enough" for many use cases (e.g., checking to see if an iterative solver has converged on a solution). If you need a specific amount of accuracy, take a look at NUnit's code -- it has some nice APIs for asserting that values are within a certain percentage or number of ulps of an expected value.
这篇关于F# - 如何比较浮点数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!