x的平方的平方根等于x

时间:2017-03-13 16:13:30

标签: floating-point precision numerical-stability

给定双精度浮点(非负)数x,它的平方的平方根总是等于它自己吗?

换句话说,如果执行以下操作,是否会有任何精度损失:

x = <non-negative double>
y = x^2
z = sqrt(y)

这样:

x == z

我对方块变为无穷大或零时的情况不感兴趣,只是符合双精度的数字。

2 个答案:

答案 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}},*/ 正确舍入

Examples:

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的答案的评论在很大程度上是正确的。如果xx*x都是正标准化数字,那么我就无法找到x != sqrt(x*x)的例子,即使是快速强力(在几个小范围内),尽管这应该不被视为证据。