Rails adds round_mode parameter support to number helpers


ActionView::Helpers::NumberHelper provides methods for converting numbers into formatted strings.

Example:

include ActiveSupport::NumberHelper
number_to_currency(45.45)
 => "$45.45" 
 
number_to_currency(45.45, precision: 0)
=> "$45" 

As shown in the above example, number to currency conversion with precision 0 resulted in rounding down the number. Sometimes, we need to round up such numbers to nearest integer than to round down. We lost $0.45 in the above example if we go by regular rounding logic.

To handle such scenarios, Rails has added round_mode parameter to number helpers.

round_mode accepts value the same as mode in Ruby BigDecimal::ROUND_MODE.

BigDecimal provides built-in support for arbitrary precision on very large or very accurate floating-point numbers in Ruby

The accepted values along with examples are:

  • :up : Round away from zero
number_to_currency(45.45, precision: 0, round_mode: :up)
=> "$46" 
  • :down, :truncate : Round towards zero (truncate)
number_to_currency(45.99, precision: 0, round_mode: :down)
=> "$45" 
  • :half_up, :default : Round towards the nearest neighbor, unless both neighbors are equidistant, in which case round away from zero. This is the default.
number_to_currency(45.5, precision: 0, round_mode: :half_up)
=> "$46" 
number_to_currency(45.49, precision: 0, round_mode: :half_up)
 => "$45" 
  • :half_down : Round towards the nearest neighbor, unless both neighbors are equidistant, in which case round towards zero.
number_to_currency(45.5, precision: 0, round_mode: :half_down)
=> "$45" 
number_to_currency(45.49, precision: 0, round_mode: :half_down)
 => "$45" 
  • :half_even, :banker : Round towards the nearest neighbor, unless both neighbors are equidistant, in which case round towards the even neighbor.
number_to_human(485000, precision: 2)
 => "490 Thousand"
number_to_human(485000, precision: 2, round_mode: :half_even)
 => "480 Thousand"
  • :ceiling, :ceil : Round towards positive infinity (ceil)
number_to_human(5545234, precision: 2, round_mode: :ceil)
=> "5.6 Million"
  • :floor : Round towards negative infinity (floor)
number_to_human(5545234, precision: 2, round_mode: :floor)
=> "5.5 Million"