aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport
diff options
context:
space:
mode:
Diffstat (limited to 'activesupport')
-rw-r--r--activesupport/CHANGELOG.md5
-rw-r--r--activesupport/lib/active_support/number_helper.rb38
-rw-r--r--activesupport/test/number_helper_test.rb4
3 files changed, 31 insertions, 16 deletions
diff --git a/activesupport/CHANGELOG.md b/activesupport/CHANGELOG.md
index 81c6246c5c..7825e69394 100644
--- a/activesupport/CHANGELOG.md
+++ b/activesupport/CHANGELOG.md
@@ -184,4 +184,9 @@
*Daniel Schierbeck*
+* Enable number_to_percentage to keep the number's precision by allowing :precision to be nil
+
+
+ *Jack Xu*
+
Please check [4-0-stable](https://github.com/rails/rails/blob/4-0-stable/activesupport/CHANGELOG.md) for previous changes.
diff --git a/activesupport/lib/active_support/number_helper.rb b/activesupport/lib/active_support/number_helper.rb
index 54cff6d394..237ef7087f 100644
--- a/activesupport/lib/active_support/number_helper.rb
+++ b/activesupport/lib/active_support/number_helper.rb
@@ -228,7 +228,7 @@ module ActiveSupport
# * <tt>:locale</tt> - Sets the locale to be used for formatting
# (defaults to current locale).
# * <tt>:precision</tt> - Sets the precision of the number
- # (defaults to 3).
+ # (defaults to 3). Keeps the number's precision if nil.
# * <tt>:significant</tt> - If +true+, precision will be the #
# of significant_digits. If +false+, the # of fractional
# digits (defaults to +false+).
@@ -250,6 +250,7 @@ module ActiveSupport
# number_to_percentage(1000, delimiter: '.', separator: ',') # => 1.000,000%
# number_to_percentage(302.24398923423, precision: 5) # => 302.24399%
# number_to_percentage(1000, locale: :fr) # => 1 000,000%
+ # number_to_percentage:(1000, precision: nil) # => 1000%
# number_to_percentage('98a') # => 98a%
# number_to_percentage(100, format: '%n %') # => 100 %
def number_to_percentage(number, options = {})
@@ -310,7 +311,7 @@ module ActiveSupport
# * <tt>:locale</tt> - Sets the locale to be used for formatting
# (defaults to current locale).
# * <tt>:precision</tt> - Sets the precision of the number
- # (defaults to 3).
+ # (defaults to 3). Keeps the number's precision if nil.
# * <tt>:significant</tt> - If +true+, precision will be the #
# of significant_digits. If +false+, the # of fractional
# digits (defaults to +false+).
@@ -331,6 +332,7 @@ module ActiveSupport
# number_to_rounded(111.2345, significant: true) # => 111
# number_to_rounded(111.2345, precision: 1, significant: true) # => 100
# number_to_rounded(13, precision: 5, significant: true) # => 13.000
+ # number_to_rounded(13, precision: nil) # => 13
# number_to_rounded(111.234, locale: :fr) # => 111,234
#
# number_to_rounded(13, precision: 5, significant: true, strip_insignificant_zeros: true)
@@ -341,7 +343,6 @@ module ActiveSupport
# # => 1.111,23
def number_to_rounded(number, options = {})
return number unless valid_float?(number)
- number = Float(number)
options = options.symbolize_keys
defaults = format_options(options[:locale], :precision)
@@ -351,22 +352,27 @@ module ActiveSupport
significant = options.delete :significant
strip_insignificant_zeros = options.delete :strip_insignificant_zeros
- if significant && precision > 0
- if number == 0
- digits, rounded_number = 1, 0
+ if precision.nil?
+ formatted_number = self.number_to_delimited(number, options)
+ else
+ number = Float(number)
+ if significant && precision > 0
+ if number == 0
+ digits, rounded_number = 1, 0
+ else
+ digits = (Math.log10(number.abs) + 1).floor
+ multiplier = 10 ** (digits - precision)
+ rounded_number = (BigDecimal.new(number.to_s) / BigDecimal.new(multiplier.to_f.to_s)).round.to_f * multiplier
+ digits = (Math.log10(rounded_number.abs) + 1).floor # After rounding, the number of digits may have changed
+ end
+ precision -= digits
+ precision = 0 if precision < 0 # don't let it be negative
else
- digits = (Math.log10(number.abs) + 1).floor
- multiplier = 10 ** (digits - precision)
- rounded_number = (BigDecimal.new(number.to_s) / BigDecimal.new(multiplier.to_f.to_s)).round.to_f * multiplier
- digits = (Math.log10(rounded_number.abs) + 1).floor # After rounding, the number of digits may have changed
+ rounded_number = BigDecimal.new(number.to_s).round(precision).to_f
+ rounded_number = rounded_number.abs if rounded_number.zero? # prevent showing negative zeros
end
- precision -= digits
- precision = 0 if precision < 0 # don't let it be negative
- else
- rounded_number = BigDecimal.new(number.to_s).round(precision).to_f
- rounded_number = rounded_number.abs if rounded_number.zero? # prevent showing negative zeros
+ formatted_number = self.number_to_delimited("%01.#{precision}f" % rounded_number, options)
end
- formatted_number = self.number_to_delimited("%01.#{precision}f" % rounded_number, options)
if strip_insignificant_zeros
escaped_separator = Regexp.escape(options[:separator])
formatted_number.sub(/(#{escaped_separator})(\d*[1-9])?0+\z/, '\1\2').sub(/#{escaped_separator}\z/, '')
diff --git a/activesupport/test/number_helper_test.rb b/activesupport/test/number_helper_test.rb
index 1fadef3637..a30e8178c7 100644
--- a/activesupport/test/number_helper_test.rb
+++ b/activesupport/test/number_helper_test.rb
@@ -79,6 +79,10 @@ module ActiveSupport
assert_equal("123.4%", number_helper.number_to_percentage(123.400, :precision => 3, :strip_insignificant_zeros => true))
assert_equal("1.000,000%", number_helper.number_to_percentage(1000, :delimiter => '.', :separator => ','))
assert_equal("1000.000 %", number_helper.number_to_percentage(1000, :format => "%n %"))
+ assert_equal("1000%", number_helper.number_to_percentage(1000, precision: nil))
+ assert_equal("1000%", number_helper.number_to_percentage(1000, precision: nil))
+ assert_equal("1000.1%", number_helper.number_to_percentage(1000.1, precision: nil))
+ assert_equal("-0.13 %", number_helper.number_to_percentage("-0.13", precision: nil, :format => "%n %"))
end
end