C ++ sqrt函数精度为正方形

时间:2013-11-22 04:37:16

标签: c++ floating-point-precision

设,x是一个整数y = x * x

然后保证sqrt(y) == x

例如,我可以确定sqrt(25)sqrt(25.0)将返回5.0,而不是5.00000000034.999999998吗?

3 个答案:

答案 0 :(得分:8)

符合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);
    }

如果通过,我认为没有理由担心。

答案 1 :(得分:4)

不,你无法保证。对于适合浮点类型尾数的动态范围的整数及其正方形(典型的C / C ++ double为2 ^ 53),您可能会很好,但不一定能保证。

您应该避免浮点值与精确值之间的等比较,尤其是精确的整数值。浮点舍入模式和其他类似的东西确实可以阻挡你。

您要么使用“比较范围”来接受“近似相等”的结果,要么根据整数重新计算算法。有多个StackOverflow问题涉及浮点相等比较。我建议你搜索它们并阅读。

对于某类问题,我在这里写了一个替代解决方案:  Find n-th root of all numbers within an interval

该解决方案采用了不同于依赖棘手的浮点运算的方法。

答案 2 :(得分:1)

你应该能够非常轻松地搜索所有值,最多2 ^ 26,但我相信答案是肯定的。在那之后,没有。

用于平方根完成的逐位数教科书算法,余数== 0,给出精确结果。然后,如果浮点库声称ieee-754合规,它也将通过任何其他方式给出该值。