在没有上溢和下溢的情况下,对于浮点数 x,x/4 是否始终等于 x/2/2(也适用于 x*4 == x*2*2)?

问题描述 投票:0回答:1

例如,据我所知,一个浮点x,其中x/n^2可能不等于x/n/n,因为在x/n/n中,这会首先创建一个中间x/n。例如:

document.write(1.23456789/49 == 1.23456789/7/7);

但是,如果没有上溢和下溢,x/4 == x/2/2 是例外吗?

我测试过:

document.write(1.23456789/4 == 1.23456789/2/2);

也适用于二进制:

1.23456789 的二进制(实际浮点数:1.2345678806304931640625):

0 01111111 00111100000011001010010

0.61728394031524658203125 的二进制 (1.2345678806304931640625/2)

0 10000000 00111100000011001010010

当乘法仅改变“指数”部分(01111111 到 10000000)时,保持小数部分不变(00111100000011001010010)。

所以目前我有一个“假设”:对于没有上溢和下溢的浮点数 x,x/4 应该始终等于 x/2/2,同样对于 x * 4==x * 2 * 2,是这样吗?

javascript floating-point precision floating-accuracy
1个回答
0
投票

我认为这仅适用于 2 的幂。所以我尝试了你的浮点数和其他素数,发现它显然只适用于 7?,所以决定暴力破解它。

function testEqualityForRandomNumbers(iterations, f) {
  let equalCount = 0;
  const failedTests = [];

  for (let a = 1; a <= iterations; a++) {
    
    const leftSide = (f / a) / a;
    const rightSide = f / (a * a);
    if (leftSide == rightSide) {
      equalCount++;
    } else {
      failedTests.push(a);
    }
  }
  return failedTests;
}

function removeFailedTests(digits, digitsToRemove) {
  let allDigits = Array.from({ length: digits }, (_, i) => i + 1);

  for (let i = 0; i < 10000; i++) {

    const f = Math.random() + 1;
    const failedTests = testEqualityForRandomNumbers(digits, f);
    
    // Remove the digits that have failed the test
    allDigits = allDigits.filter((digit) => !failedTests.includes(digit));

    
    // If no more digits are left, stop the process
    if (allDigits.length === 0) {
      console.log('All digits have failed the test.');
      break;
    }
  }
  console.log(allDigits)
  
}

const digits = 10000;
removeFailedTests(digits);


[1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192]

对于随机浮点数,是的,只有 2 的指数幸存。但此时我更好奇的是 7 和你的 1.23456...

© www.soinside.com 2019 - 2024. All rights reserved.