Exponentiation in Ruby 1.8.7 Returns Wrong Answers

Exponentiation in Ruby 1.8.7 Returns Wrong Answers

When calculating, Ruby is supposed to convert from Fixnum to Bignum when the numbers go beyond the bounds of Fixnum. For older versions of Ruby, this fails with the ** operator:

$ ruby --version
ruby 1.8.7 (2012-02-08 patchlevel 358) [universal-darwin12.0]
$ irb
>> 2 ** 62
=> 4611686018427387904
>> 2 ** 63
=> -9223372036854775808
>> 2 ** 64
=> 0

Where it fails depends on the word size of the architecture. 64-bit words on the iMac in this example. Internally, the Fixnum is cast to a long integer, and the operator is handled with longs. The longs overflow at word size, and Ruby is ungracefully handling this by returning 0.

Note that the * operator works correctly (converting to Bignum), where the ** fails:

>> a = 2 ** 62
=> 4611686018427387904
>> 2 ** 63
=> -9223372036854775808
>> a * 2
=> 9223372036854775808
>> 2 ** 64
=> 0
>> a * 4
=> 18446744073709551616

Moving to a newer version of Ruby will fix this. If you can't move to a newer version, then avoid using Fixnum and ** with large powers.

Different exponent behavior for different ruby versions

I am reasonaly certain that you are experiencing the bug mentioned in this post.

It appears as though it was fixed by this commit to Ruby trunk, which made it to Ruby 1.9.3-p0 and greater.

Interesting bug? in OSX preinstalled Ruby (1.8.7)

This was a bug on Ruby implementation that has been fixed by patch 358.

It was cause by the fact that the returned value of the multiplication was declared volatile which means that couldn't be optimized.
The default C optimization wouldn't have caused the overflow, therefore the volatile keyword was removed.

On Ruby 1.9.3 works correctly.

Ruby 1.8.7 RegExp doesn't work with meta-character \h

You're right that \h doesn't seem to be recognised by the standard Ruby 1.8.7 regexp library. This can be confirmed using Rubular. If you need 1.8 compatibility in your code without using any additional gems I think your only alternative is to use an equivalent character class [0-9a-fA-F].

Why is Ruby Bignum not working?

It was a bug in Ruby 1.8.7. It has been fixed by this commit.
Just upgrade to the latest version and everything will work fine.

Here are some tests on 1.9.3:

Sample Image

Here is the text representation (for blind users):

1.9.3p362 :001 > 10 ** 18
=> 1000000000000000000
1.9.3p362 :002 > 10 ** 19
=> 10000000000000000000
1.9.3p362 :003 > 10 ** 20
=> 100000000000000000000
1.9.3p362 :004 > 10 ** 21
=> 1000000000000000000000
1.9.3p362 :005 > 10 ** 22
=> 10000000000000000000000
1.9.3p362 :006 > 10 ** 23
=> 100000000000000000000000

Here's the list of commands I've run:

irb
10 ** 18
10 ** 19
10 ** 20
10 ** 21
10 ** 22
10 ** 23

Large multiplication output coming out negative in Ruby

Looks like this was a bug in 1.8.7 that was fixed by patch 358: Exponentiation in Ruby 1.8.7 Returns Wrong Answers

(The result of a power computation in numeric.c wasn't declared as volatile before this commit, after which overflow behavior seems to have been fixed.)

ruby function that checks if one of given number is integer power of another one

You have a precision problem, as you could see if you used irb

irb(main):001:0> Math.log(216)
=> 5.375278407684165
irb(main):002:0> Math.log(6)
=> 1.791759469228055
irb(main):003:0> Math.log(216)/Math.log(6)
=> 3.0000000000000004

And unfortunately 3.0000000000000004 isn't equal to 3.

You could possibly round the result...

a = (Math.log(m)/Math.log(n)).round(14)

TextMate's Execute and Update ‘# = ’ Markers evaluates with ruby 1.8 instead of 1.9

This is a good reference.

http://cl.ly/23Ylhttp://cl.ly/23Yl/rvm_textmate.png

Make sure you are running all the new versions.

Out of the box, rvm ships with a ruby binary, typically in ~/.rvm/bin (or, in system wide installs, inside of /usr/local/bin), that will perform the following steps before executing ruby:

Load up RVM
Look for any RVMRC files and load them
Execute as a normal ruby

This approach makes it possible to have the ruby switched on a per-project basis without any extra work. With rvm installed, this is a matter of taking the full path to rvm-auto-ruby, found via:

$ which rvm-auto-ruby

And in the advanced section of the textmate preferences, either adding or changing the TM_RUBY variable to point to the given path, like shown in this screenshot with an example installation.

Source: https://rvm.io/integration/textmate/

FWIW: Josh Cheek is great (rubykickstart)



Related Topics



Leave a reply



Submit