简体   繁体   中英

NoMemoryError: failed to allocate memory using BigDecimal .to_s method

I use Ruby 2.2.3 and Rails 4.2.3 . I get an NoMemoryError: failed to allocate memory using the following code in irb console:

# Using 123e+1000000000000000000
BigDecimal('123e+1000000000000000000').to_s
#=> NoMemoryError: failed to allocate memory

But this example with a more bigger number works:

# Using 123e+1000000000000000000000000000000000
BigDecimal('123e+1000000000000000000000000000000000').to_s
#=> "Infinity"

Here the code of BigDecimal : https://github.com/rails/rails/blob/v4.2.3/activesupport/lib/active_support/core_ext/big_decimal/conversions.rb

The fact that you run out of memory is nothing strange. The number 123e+1000000000000000000 has a quintillion zeroes. Representing it as a string would take a quintillion characters.

At one byte per character, you're looking at (roughly) 10^18 bytes, 10^15 kilobytes, 10^12 megabytes, or 10^9 gigabytes. So unless you have in the range of a billion gigabytes of RAM, it's not going to work that well.

Once the number passed to the BigDecimal constructor passes the biggest number that can be represented on your system, it will overflow to the constant BigDecimal::INFINITY , which when converted to a string, is just Infinity , and can clearly fit in memory:

BigDecimal('123e+1000000000000000000000000000000000') == BigDecimal::INFINITY
#=> true

Why not convert it to a float? This works for me:

BigDecimal('123e+1000000000000000000').to_f
=> Infinity

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM