C++ sqrt 函数的全平方精度
Posted
技术标签:
【中文标题】C++ sqrt 函数的全平方精度【英文标题】:C++ sqrt function precision for full squares 【发布时间】:2013-11-22 04:37:16 【问题描述】:设,x
是一个整数,y = x * x
。
那么保证sqrt(y) == x
?
例如,我能否确定sqrt(25)
或sqrt(25.0)
将返回5.0
,而不是5.0000000003
或4.999999998
?
【问题讨论】:
如果5不能准确表示,怎么可能呢?您可以期望的最好结果是它会截断为 5。 既然5是整数,不应该精确表示吗?我在某处读到 double 可以准确地将值存储在整数范围内。 @RafiKamal:一个 IEEE-754 64 位双精度浮点数可以准确地表示整个 32 位有符号和无符号整数范围而不会丢失。在那种情况下,这只控制类型转换。它不控制计算sqrt(x)
的浮点库的精度。
相关问题:Floating point inaccuracy examples
@JoeZ 谢谢,我明白了
【参考方案1】:
符合 IEEE-754 标准的关于基本操作允许错误的实现(sqrt
是一个示例)要求对值进行正确舍入。
这意味着误差将小于 1/2 ULP(最后一个单位)或基本上尽可能接近实际答案。
要回答您的问题,如果实际答案完全可以用 double
表示,那么您将得到准确的答案。
注意:C++ 标准并不能保证这一点,而是 IEEE-754 标准,这对大多数人来说可能不是问题。
最终,一个简单的测试应该足以满足您的目的:
for(int i = 0; i < (int)std::sqrt(std::numeric_limits<int>::max()); i++)
assert((int)(double)i == i);//Ensure exactly representable, because why not
assert(std::sqrt((double)i*i) == i);
如果这一切都过去了,我认为没有任何理由担心。
【讨论】:
【参考方案2】:不,您不能得到保证。对于适合浮点类型尾数动态范围的整数及其平方(对于典型的 C/C++ double
,为 2^53),您可能没问题,但不一定能保证。
您应该避免在浮点值和精确值之间进行相等比较,尤其是精确整数值。浮点舍入模式和其他类似的东西真的会妨碍你。
您要么想使用“比较范围”来接受“近似相等”的结果,要么根据整数重新调整算法。有多个 *** 问题涉及浮点相等比较。我建议你搜索它们并阅读。
对于某一类问题,我在这里写了一个替代解决方案: Find n-th root of all numbers within an interval
该解决方案采用了不同于依赖复杂浮点运算的方法。
【讨论】:
【参考方案3】:您应该能够很容易地暴力搜索高达 2^26 的所有值,但我相信答案是肯定的。在那个数字之后,没有。
平方根的逐位数教科书算法以余数 == 0 结束,给出了准确的结果。再说一次,如果浮点库声称符合 ieee-754,它也会通过任何其他方式给出这个值。
【讨论】:
以上是关于C++ sqrt 函数的全平方精度的主要内容,如果未能解决你的问题,请参考以下文章
R语言数学函数:abs绝对值sqrt平方根ceiling向上近似整数floor向下近似整数trunc去除小数部分round近似到指定小数位signif近似到有效数字三角函数指数对数