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:
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
Converting a Hash into a Nested Hash
Interpretation as a Local Variable Overrides Method Name
Rails 3.1 - Has_And_Belongs_To_Many Deprecated
Faulty Ruby Compilation with Rvm: Getting 'Undefined Symbol: Rb_Digest_Md5_Init' While Running Racku
Ruby on Rails Send_File Doesn't Work Until I Refresh the Page
Extract All Email Addresses from Some .Txt Documents Using Ruby
Add Space After Commas Only If It Doesn't Already
Can't Install Gems Because "Undefined Method 'Invoke_With_Build_Args' for Nil:Nilclass"
Ruby: Inject Issue When Turning Array into Hash
Use Rvm to Force Specific Ruby in Xcode Run Script Build Phase
Exponentiation in Ruby 1.8.7 Returns Wrong Answers
Undefined Namespace Prefix in Nokogiri and Xpath
How to "Unflatten" a Ruby Array
How Does This Ruby Injection Magic Work
How to Solve Insecure World Writable Dir /Usr in Path,Mode 040777 Warning on Ruby