2016-01-22 1 views
0

Я использую Ruby 2.2.3 и Rails 4.2.3. Я получаю NoMemoryError: failed to allocate memory используя следующий код в IRB консоли:NoMemoryError: не удалось выделить память с использованием метода BigDecimal .to_s

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

Но этот пример с более большим числом работ:

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

Здесь код BigDecimal: https://github.com/rails/rails/blob/v4.2.3/activesupport/lib/active_support/core_ext/big_decimal/conversions.rb

+0

Что вы хотите сказать? – sawa

ответ

1

Тот факт, что у вас закончилась память, ничего странного. Число 123e+1000000000000000000 имеет квинтиллион нулей. Представляя его как строку, вы должны взять квинтиллион персонажей.

В один байт на символ, вы смотрите на (примерно) 10^18 байт, килобайт, 10^1510^12 мегабайта или 10^9 гигабайта. Поэтому, если у вас нет диапазона в миллиард гигабайт оперативной памяти, это не будет работать так хорошо.

После того, как номер, передаваемый в BigDecimal конструктор проходит самое большое число, которое может быть представлено в вашей системе, она будет переливаться на постоянной BigDecimal::INFINITY, что при преобразовании в строку, просто Infinity, и может четко вписываться в памяти:

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

Почему не конвертировать его в поплавок? Это работает для меня:

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

Хорошо, справа. Но .to_s должен работать в любом случае. – phlegx

+0

@phlegx, что вы подразумеваете под «должен работать»? Если на вашем компьютере недостаточно памяти для выделения для этой строки, тогда хорошо ... может быть, хорошо, что это не попытка –

 Смежные вопросы

  • Нет связанных вопросов^_^