skip to Main Content

For example, as I know, a float point x, which x/n^2 may not be equal to x/n/n, because in x/n/n, which would create an intermediate x/n first. For example:

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

However, is x/4 == x/2/2 an exception, if no overflow and underflow, which is always true?

I tested:

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

Also for binary:

Binary of 1.23456789 (actual float : 1.2345678806304931640625) :

0 01111111 00111100000011001010010

binary of 0.61728394031524658203125 (1.2345678806304931640625/2)

0 10000000 00111100000011001010010

which seems when multiply only varies the "exponent" part (01111111 to 10000000), keeping the fraction part unchanged (00111100000011001010010).

So currently I have a "hypothesis" : for float number x without overflow and underflow, x/4 should always be equal to x/2/2, also for x * 4==x * 2 * 2, is that true?

2

Answers


  1. I thought it would be only true for powers of 2. So I tried with your float and other prime numbers and found that it was apparently only not true for 7?, so decided to brute force it.

    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]
    

    For random float numbers, yeh, only exponents of two survive. But at this point I’m more curious about the 7 and your 1.23456…

    Login or Signup to reply.
  2. Without overflow and underflow, since the radix is 2, multiplications and divisions by powers of 2 are always exact operations. Since no rounding is involved here, x/4 is equal to x/2/2 and x*4 is equal to x*2*2, as this is true on the real numbers.

    Note that if x is ±0, the sign of the result will be the same with both expressions.

    EDIT: More generally, in each expression, you may have a single multiplication or division by a number that is not a power of 2. For instance, x/2/3 and x/3/2 are always equal to x/6.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search