C++ C++;全正方形的sqrt函数精度

C++ C++;全正方形的sqrt函数精度,c++,floating-point-precision,C++,Floating Point Precision,设,x是一个整数,y=x*x 那么是否保证sqrt(y)==x 例如,我是否可以确保sqrt(25)或sqrt(25.0)将返回5.0,而不是5.0000000003或4.9999999999 8?不,您不能得到保证。对于适合浮点类型尾数动态范围的整数及其平方(对于典型的C/C++double),您可能是可以的,但不一定保证 您应该避免浮点值和精确值之间的相等比较,尤其是精确整数值。浮点舍入模式和其他类似的东西真的会妨碍你 您可以使用“比较范围”来接受“近似相等”的结果,也可以根据整数重新构建算

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

那么是否保证
sqrt(y)==x


例如,我是否可以确保
sqrt(25)
sqrt(25.0)
将返回
5.0
,而不是
5.0000000003
4.9999999999 8

不,您不能得到保证。对于适合浮点类型尾数动态范围的整数及其平方(对于典型的C/C++
double
),您可能是可以的,但不一定保证

您应该避免浮点值和精确值之间的相等比较,尤其是精确整数值。浮点舍入模式和其他类似的东西真的会妨碍你

您可以使用“比较范围”来接受“近似相等”的结果,也可以根据整数重新构建算法。有多个StackOverflow问题涉及浮点等式比较。我建议你搜索一下,仔细阅读

对于某类问题,我在这里写了一个备选解决方案:


与依赖复杂的浮点运算不同,该解决方案采用了不同的方法。

符合IEEE-754基本运算允许误差标准的实现(其中
sqrt
就是一个例子)要求正确舍入值。
这意味着误差将小于1/2 ULP(最后的单位)或基本上尽可能接近实际答案

要回答您的问题,如果实际答案可以用
双精度表示,那么您将得到准确的答案

注:这不是由C++标准保证的,而是IEEE-75标准,这对大多数人来说可能不是问题。 最终,一个简单的测试应该足以满足您的目的:

    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);
    }
for(int i=0;i<(int)std::sqrt(std::numeric_limits::max();i++)
{
assert((int)(double)i==i);//确保完全可表示,因为为什么不能
断言(std::sqrt((double)i*i)==i);
}

如果通过了,我看不出有任何理由担心。

您应该能够非常轻松地对2^26以下的所有值进行暴力搜索,但我相信答案是肯定的。在那个号码之后,没有


平方根的逐位教科书算法以余数==0结束,给出精确的结果。然后,如果浮点库声明符合ieee-754,它也会通过任何其他方式给出该值。

如果5不能准确表示,它怎么可能?你能期望的最好结果是它被截断为5。因为5是一个整数,它不应该被精确表示吗?我在某个地方读到,double可以准确地存储整数范围内的值。@RafiKamal:IEEE-754 64位双精度浮点可以准确地表示32位有符号和无符号整数的整个范围而不会丢失。在这种情况下,它只控制类型转换。它不控制计算
sqrt(x)
的浮点库的精度。相关问题:@JoeZ谢谢,我理解了