rubyjs / therubyracer

Embed the V8 Javascript Interpreter into Ruby
1.66k stars 193 forks source link

Wrong big int converting #248

Closed bachue closed 11 years ago

bachue commented 11 years ago
require 'v8'

v8 = V8::Context.new
r = v8.eval 'a = {"b": 310399688698392577}'
r[b].to_i # => 310399688698392576 (expected: 310399688698392577)

The Ruby Version is 1.9.3 The V8 Version is 0.11.4

ignisf commented 11 years ago

@bachue, this is the expected behaviour of JavaScript. From http://www.hunlock.com/blogs/The_Complete_Javascript_Number_Reference :

All numbers in Javascript are 64bit (8 bytes) floating point numbers which yields an effective range of 5e-324 (negative) to 1.7976931348623157e+308 (positive) at the time this article was written (this may eventually change to 128 bits in the future as 64 bit processors become commonplace and the ECMA standards evolve).

_Integers are considered reliable (numbers without a period or exponent notation) to 15 digits (9e15) [1]._ Floating point numbers are considered only as reliable as possible and no more! This is an especially important concept to understand for currency manipulation as 0.06 + 0.01 resolves to 0.06999999999999999 instead of 0.07.

bachue commented 11 years ago

@ignisf OK, I found it's not a V8 issue, also not a Ruby issue or Javascript issue. It's an issue of all languages, include Java https://gist.github.com/kenshin54/5128257.

ignisf commented 11 years ago

If you are referring to the limited floating point precision – yes – it is common throughout all languages. However most of the other languages will either raise an integer overflow exception, or construct a Bignim or some equivalent when using such a large integer.

Anyway, this is not an issue with therubyracer.