对于任何浮点数x、y和整数n,其中const y=n-x,且0<=x,y,n<=MAX_VALUE,x+y==n是否总是成立?

3

例如:

const n=5;
const x=1.23;
const y=n-x;
document.write(x+y==n);

关于n=5,x=1.23,y=5-1.23(四舍五入后的值)的代码打印出true。我认为这只是一个“幸运”的情况,因为我认为可能会有一些情况,使得n-x会四舍五入到某个值,以至于x+y再次不等于n。但是我尝试使用for循环来找到一些错误的情况:

for(let i=0;i<100000;i++){
  const n=Math.floor(Math.random()*10000);
  const x=Math.random()*5000;
  const y=n-x;
  if(x+y!=n){
    document.write(x+","+y+","+n);
    break;
  }
}

令人惊讶的是,连续多次运行时不会打印任何异常。

所以我的问题是,对于任何浮点数x、y、整数n,其中const y=n-x,并且o<=x、y、n<=MAX_VALUE,是否总是成立x+y==n?如果是,原因是什么?是否存在任何错误的情况?

附注:似乎对于x>n也是正确的:

for(let i=0;i<100000;i++){
      const n=Math.floor(Math.random()*10000);
      const x=10000+Math.random()*5000;
      const y=n-x;
      if(x+y!=n){
        document.write(x+","+y+","+n);
        break;
      }
}

但不适用于x为负数的情况:

for(let i=0;i<100000;i++){
      const n=Math.floor(Math.random()*10000);
      const x=Math.random()*-5000;
      const y=n-x;
      if(x+y!=n){
        document.write(x+","+y+","+n);
        break;
      }
}

这是什么原因?


64位IEEE754二进制浮点数中,2 ** ±52附近的值通常是有趣的地方,因为这是你开始失去精度的地方。以“十六进制格式”打印值可以帮助,js-hexfloat是我在JS中找到的最好的工具,在C中使用printf时是%a转换,std::hexfloat在C ++中或者在Python中使用float.hex() - Sam Mason
1个回答

1

不是这样的。这里有一个反例:

const n=5847425060810559;
const x=87667.5;
const y=n-x;
document.write(x+y==n);
document.write("<br>lhs = " + (x+y) + "<br>rhs = " + n);


1
n = 2 ** 52 + 1; x = 0.5 和 n = 2 ** 53 + 2; x = 1 是反例,可以更容易地看出发生了什么。 - Sam Mason

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接