给定双精度浮点(非负)数x
,它的平方的平方根总是等于它自己吗?
换句话说,如果执行以下操作,是否会有任何精度损失:
x = <non-negative double>
y = x^2
z = sqrt(y)
这样:
x == z
我对方块变为无穷大或零时的情况不感兴趣,只是符合双精度的数字。
答案 0 :(得分:2)
将一个数字平方,产生两倍于原始值中位数的值。因此,如果x太大,则x^2
中的某些位丢失,x
无法从y
完全恢复[编辑:仍然可以通过适当的舍入从y获取x]。在IEEE-754双精度的情况下,如果x
在有效位数部分中具有多于26位,则y
的结果将被截断。这是最简单的情况。
如果x
具有很少的有效位,但指数非常大或非常小,则x^2
可能对于双精度来说太大而且会变为inf
或非正规数,在这种情况下没有恢复x
的方法。
如果x
不是太大或太小,则sqrt(y)
将等于x
,因为IEEE-754标准需要+
,-
,{ {1}},*
和/
正确舍入 。
sqrt
答案 1 :(得分:1)
#include <stdio.h>
#include <math.h>
int main(void) {
double x = 1.0000000000000001E-160;
double square = x*x;
double root = sqrt(square);
if (root != x) {
printf("%.20g\n", x);
printf("%.20g\n", root);
}
}
输出
1.0000000000000001466e-160 9.9999443357584897793e-161
这里发生的事情是x
足够大,其方形非零,但足够小,其方形只能表示为非规范化数字,这会降低可用的精度。
我的印象是@ MarkDickinson对@LưuVĩnhPhúc的答案的评论在很大程度上是正确的。如果x
和x*x
都是正标准化数字,那么我就无法找到x != sqrt(x*x)
的例子,即使是快速强力(在几个小范围内),尽管这应该不被视为证据。