Raf*_*mal 7 c++ floating-point-precision
设,x
是一个整数和y = x * x
.
那保证sqrt(y) == x
吗?
例如,我可以确定sqrt(25)
或sqrt(25.0)
将返回5.0
,不是5.0000000003
或4.999999998
?
符合IEEE-754标准的基本操作允许错误的实现(sqrt
例如)需要正确舍入值.
这意味着误差将小于1/2 ULP(最后一个单位)或基本上尽可能接近实际答案.
要回答你的问题,如果实际答案完全由a表示,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);
}
Run Code Online (Sandbox Code Playgroud)
如果这个过去了,我认为没有理由担心.
不,您不能保证。对于适合浮点类型尾数动态范围的整数及其平方(典型的C / C ++ double
值为2 ^ 53 ),您可能会没事,但不一定可以保证。
您应避免在浮点值和精确值(尤其是精确整数值)之间进行等值比较。浮点舍入模式和其他类似的东西确实会给您带来麻烦。
您要么想要使用“比较范围”来接受“近似相等”的结果,要么要使用整数来重铸算法。有多个StackOverflow问题涉及浮点相等比较。我建议您搜索并阅读。
对于某类问题,我在这里写了一个替代解决方案: 在一个间隔内找到所有数字的第n个根
该解决方案采用了不同于依赖棘手浮点算法的方法。