How to Convert a Ruby Bigdecimal to a 2-Decimal Place String

How can I convert a BigDecimal to a 2-decimal-place string?

How about combining BigDecimal#truncate and String#%? :

"%.2f" % BigDecimal("7.1762").truncate(2)
# => "7.17"
"%.2f" % BigDecimal("4.2").truncate(2)
# => "4.20"

Ruby output numbers to 2 decimal places

First of all, you should not use floats to represent monetary values. So instead, let's use a more appropriate type: (there's also the Ruby Money gem)

require 'bigdecimal'

my_hash = {
foo: BigDecimal.new('1.00'),
bar: BigDecimal.new('4.50'),
abc: BigDecimal.new('0.00'),
xyz: BigDecimal.new('1.23')
}

There are several options to represent monetary values. All of the following JSON strings are valid according to the JSON specification and all require special treatment upon parsing. It's up to you to choose the most appropriate.

Note: I'm implementing a custom to_json method to convert the BigDecimal instances to JSON using Ruby's default JSON library. This is just for demonstration purposes, you should generally not patch core (or stdlib) classes.


1. Numbers with fixed precision

This is what you asked for. Note that many JSON libraries will parse these numbers as floating point values by default.

class BigDecimal
def to_json(*)
'%.2f' % self
end
end
puts my_hash.to_json

Output:

{"foo":1.00,"bar":4.50,"abc":0.00,"xyz":1.23}

2. Numbers as strings

This will work across all JSON libraries, but storing numbers as strings doesn't look quite right to me.

class BigDecimal
def to_json(*)
'"%.2f"' % self
end
end
puts my_hash.to_json

Output:

{"foo":"1.00","bar":"4.50","abc":"0.00","xyz":"1.23"}

3. Numbers as integers

Instead of representing monetary values as fractional numbers, you simply output the cents as whole numbers. This is what I usually do.

class BigDecimal
def to_json(*)
(self * 100).to_i.to_s
end
end
puts my_hash.to_json

Output:

{"foo":100,"bar":450,"abc":0,"xyz":123}

Ruby big decimal with 2 numbers after the decimal point

It can, but this is a kind of output format.

sprintf( "%.02f", a)
# => "1.00"

You can define a method like this:

class BigDecimal
def to_string
sprintf( "%.02f", self)
end
end

a.to_string
=> "1.00"

As suggested by @CarySwoveland, you also can write like this

sprintf( "%.02f" % a)
sprintf( "%.02f %.02f %.02f" % [a, b, c])

How do I format a BigDecimal to only show as many decimal digits as needed?

For your views, look at the methods from the NumberHelper, in particular the number_with_precision, http://api.rubyonrails.org/classes/ActionView/Helpers/NumberHelper.html#method-i-number_with_precision

Particularly, you want the strip_insignificant_zeros option.

Ruby convert 2 decimal string into a number and keep the two decimals

Float

You can convert "5565.80" to a float :

value = "5565.80".to_f
# 5565.8

And then display the value with two decimals :

'%.2f' % value
# "5565.80"

A float has double-precision in Ruby, so your value will actually be :

5565.800000000000181898940354...

As a float, you cannot save exactly 5565.80.

Exact values

Integer

If you want exact values (e.g. for currency), you could use integers for cents :

"5565.80".delete('.').to_i
# 556580

When you need the corresponding float, you could divide it by 100.0.

Decimal

If you're working with a database, you could use decimal(20,2) or something equivalent.

BigDecimal

You could also use BigDecimal :

require 'bigdecimal'
BigDecimal.new("5565.80")

It will save the exact value but will be much slower than int or float.

Handling BigDecimal trailing zero's Ruby

sprintf("%2.f", v) should work. The options for sprintf can be found at

http://ruby-doc.org/core-2.3.0/Kernel.html#method-i-sprintf

Also, if you're using Rails, the number_with_precision helper is probably easier to use - you can find the documentation at http://api.rubyonrails.org/classes/ActionView/Helpers/NumberHelper.html#method-i-number_with_precision

Parse a decimal value from a String in Ruby

(Found it myself after a bit of digging)

BigDecimal is the standard Ruby fixed-point type, and it's constructor takes a String and handles the parsing for you:

BigDecimal.new("123.45")

How do you round a float to 2 decimal places in JRuby?

Float#round can take a parameter in Ruby 1.9, not in Ruby 1.8. JRuby defaults to 1.8, but it is capable of running in 1.9 mode.



Related Topics



Leave a reply



Submit