Search code examples
rubydecimalbigdecimal

Can I maintain the accuracy of a large number after cube-rooting it and then re-cubing it?


I'm trying to do a calculation with a large number x, where I take the cube root of it (j = x**(1/3.0)) and then re-cube it (z = j**3). x should be equal to j, and it is when using small numbers like 26 and then rounding, but for very large numbers I'm having problems with mantaining the accuracy:

1.9.3-p385 :119 > x = 34567898765434567898765677654125 ** 3
1.9.3-p385 :120 > x = BigDecimal.new(x)
1.9.3-p385 :121 > cube_root = x**(1/3.0) 
1.9.3-p385 :122 > recubed = cube_root**3
1.9.3-p385 :123 > recubed == x
 => false 
1.9.3-p385 :124 > recubed.to_i
=> 41306551989787317397975170279355443182356154696413548486992943670408047235040641261388609159478 
1.9.3-p385 :125 > x.to_i
=> 41306551989788217308443399821163722262582437385123598833127062833015560078766131667297533203125 

If it's not possible to end up with a close approximate, is there a way to end up with a more accurate one where more of the most significant bits are the same?


Solution

  • Change this line

    cube_root = x ** (1 / 3.0)
    

    To something like this

    cube_root = x ** BigDecimal('0.' + '3' * 100)
    

    Or

    cube_root = x ** BigDecimal('1/3'.to_r, 100)
    

    And you'll see the difference.

    1.9.3p194 :203 > recubed.to_i
     => 41306551989788217308443399821163722262582437385123598833127062833015560078766131667297533203124 
    1.9.3p194 :204 > x.to_i
     => 41306551989788217308443399821163722262582437385123598833127062833015560078766131667297533203125
    

    And that is because 1 / 3.0 is a very not accurate thing.