Skip to content

Commit

Permalink
Merge pull request #49466 from ghiculescu/number_converter_big_number
Browse files Browse the repository at this point in the history
`NumberHelper`: handle very large numbers
  • Loading branch information
rafaelfranca committed Oct 3, 2023
1 parent b2e8468 commit 06e13c1
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 9 deletions.
13 changes: 10 additions & 3 deletions activesupport/lib/active_support/number_helper/number_converter.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# frozen_string_literal: true

require "bigdecimal"
require "bigdecimal/util"
require "active_support/core_ext/big_decimal/conversions"
require "active_support/core_ext/hash/keys"
require "active_support/i18n"
Expand Down Expand Up @@ -128,7 +130,7 @@ def initialize(number, options)
def execute
if !number
nil
elsif validate_float? && !valid_float?
elsif validate_float? && !valid_bigdecimal
number
else
convert
Expand Down Expand Up @@ -173,8 +175,13 @@ def default_value(key)
key.split(".").reduce(DEFAULTS) { |defaults, k| defaults[k.to_sym] }
end

def valid_float?
Float(number, exception: false)
def valid_bigdecimal
case number
when Float, Rational
number.to_d(0)
else
BigDecimal(number, exception: false)
end
end
end
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ class NumberToCurrencyConverter < NumberConverter # :nodoc:
def convert
format = options[:format]

number_f = valid_float?
if number_f
if number_f.negative?
number_f = number_f.abs
format = options[:negative_format] if (number_f * 10**options[:precision]) >= 0.5
number_d = valid_bigdecimal
if number_d
if number_d.negative?
number_d = number_d.abs
format = options[:negative_format] if (number_d * 10**options[:precision]) >= 0.5
end
number_s = NumberToRoundedConverter.convert(number_f, options)
number_s = NumberToRoundedConverter.convert(number_d, options)
else
number_s = number.to_s.strip
format = options[:negative_format] if number_s.sub!(/^-/, "")
Expand Down
1 change: 1 addition & 0 deletions activesupport/test/number_helper_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ def test_number_to_phone

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

0 comments on commit 06e13c1

Please sign in to comment.