Skip to content

Commit 7cc4de0

Browse files
authored
Merge pull request rails#49466 from ghiculescu/number_converter_big_number
`NumberHelper`: handle very large numbers
2 parents e659f46 + ce321c4 commit 7cc4de0

File tree

3 files changed

+17
-9
lines changed

3 files changed

+17
-9
lines changed

activesupport/lib/active_support/number_helper/number_converter.rb

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# frozen_string_literal: true
22

3+
require "bigdecimal"
4+
require "bigdecimal/util"
35
require "active_support/core_ext/big_decimal/conversions"
46
require "active_support/core_ext/hash/keys"
57
require "active_support/i18n"
@@ -128,7 +130,7 @@ def initialize(number, options)
128130
def execute
129131
if !number
130132
nil
131-
elsif validate_float? && !valid_float?
133+
elsif validate_float? && !valid_bigdecimal
132134
number
133135
else
134136
convert
@@ -173,8 +175,13 @@ def default_value(key)
173175
key.split(".").reduce(DEFAULTS) { |defaults, k| defaults[k.to_sym] }
174176
end
175177

176-
def valid_float?
177-
Float(number, exception: false)
178+
def valid_bigdecimal
179+
case number
180+
when Float, Rational
181+
number.to_d(0)
182+
else
183+
BigDecimal(number, exception: false)
184+
end
178185
end
179186
end
180187
end

activesupport/lib/active_support/number_helper/number_to_currency_converter.rb

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,13 @@ class NumberToCurrencyConverter < NumberConverter # :nodoc:
1010
def convert
1111
format = options[:format]
1212

13-
number_f = valid_float?
14-
if number_f
15-
if number_f.negative?
16-
number_f = number_f.abs
17-
format = options[:negative_format] if (number_f * 10**options[:precision]) >= 0.5
13+
number_d = valid_bigdecimal
14+
if number_d
15+
if number_d.negative?
16+
number_d = number_d.abs
17+
format = options[:negative_format] if (number_d * 10**options[:precision]) >= 0.5
1818
end
19-
number_s = NumberToRoundedConverter.convert(number_f, options)
19+
number_s = NumberToRoundedConverter.convert(number_d, options)
2020
else
2121
number_s = number.to_s.strip
2222
format = options[:negative_format] if number_s.sub!(/^-/, "")

activesupport/test/number_helper_test.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ def test_number_to_phone
6969

7070
def test_number_to_currency
7171
[@instance_with_helpers, TestClassWithClassNumberHelpers, ActiveSupport::NumberHelper].each do |number_helper|
72+
assert_equal("$123,456,789,012,345,678.91", number_helper.number_to_currency("123456789012345678.91"))
7273
assert_equal("$1,234,567,890.50", number_helper.number_to_currency(1234567890.50))
7374
assert_equal("$1,234,567,890.51", number_helper.number_to_currency(1234567890.506))
7475
assert_equal("-$1,234,567,890.50", number_helper.number_to_currency(-1234567890.50))

0 commit comments

Comments
 (0)