设,x
是一个整数y = x * x
。
然后保证sqrt(y) == x
?
例如,我可以确定sqrt(25)
或sqrt(25.0)
将返回5.0
,而不是5.0000000003
或4.999999998
吗?
答案 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合规,它也将通过任何其他方式给出该值。