Displaying an output in Ruby to 2 decimal places
You have to add a dot in the format to say you want the 2
to be the precision after the decimal dot:
s = '%.2f' % @price
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.
How can I make eval return a number with decimal places?
All you need is the denominator of the division to be floating point and Ruby will understand to use floating point arithmetic on the expression instead of the default integer arithmetic:
irb(main):001:0> a = 5
irb(main):002:0> b = 4
irb(main):003:0> a / b
=> 1
irb(main):004:0> a / b.to_f
=> 1.25
irb(main):005:0> (a + b) / b.to_f
=> 2.25
Edit
To further clarify - It actually has nothing to do with eval
in itself. It's just the way Ruby (and most other languages) handle arithmetic expressions. Most expressions are done with integer arithmetic by default.
When doing division in Ruby all you need is either dividend or divisor to be float to trigger floating point arithmetic.
rails decimal scale = 2 not working
scale
specifies number of digits after the decimal point preserved in the database. Saving 1.234
will round to 1.23
, 500.00
will be stored as 500.00
.
In Ruby on Rails, they will be represented as a BigDecimal
. The BigDecimal
will not know about the format that was used in the DB. If its value is 500.0
, its to_s
method will output it as 500.0
because that's accurate enough.
To format the values as currency, use the number_to_currency
helper method.
Also see Ruby on Rails: best method of handling currency / money and Does Ruby have any number formatting classes?
Inconsistent conversion of Float into Decimal in Ruby
So why is this happening?
TL;DR different precisions are used.
Long answer:
64.4.to_d
calls bigdecimal/util
's Float#to_d
:
def to_d(precision=nil)
BigDecimal(self, precision || Float::DIG)
end
Unless specified, it uses an implicit precision of Float::DIG
which is 15
for current implementations:
Float::DIG
#=> 15
So 64.4.to_d
is equivalent to:
BigDecimal(64.4, Float::DIG)
#=> #<BigDecimal:7fd7cc0aa838,'0.644E2',18(36)>
BigDecimal#*
on the other hand converts a given float argument via:
if (RB_TYPE_P(r, T_FLOAT)) {
b = GetVpValueWithPrec(r, DBL_DIG+1, 1);
}
DBL_DIG
is the C-equivalent of Float::DIG
, so it's basically:
BigDecimal(64.4, Float::DIG + 1)
#=> #<BigDecimal:7fd7cc098408,'0.6440000000 000001E2',27(36)>
That said, you can get the expected result if you provide the precision explicitly, either:
f.to_d(16) == 1.to_d * f
#=> true
or:
f.to_d == 1.to_d.mult(f, 15)
#=> true
and of course by explicitly converting f
via to_d
:
f.to_d == 1.to_d * f.to_d
#=> true
Isn't this a bug?
It looks like one, you should file a bug report.
Note that neither 0.644E2
, nor 0.6440000000000001E2
is an exact representation of the given floating point number. As already noted by Eli Sadoff, 64.4
's exact value is 64.400000000000005684341886080801486968994140625
, so the most exact BigDecimal
representation would be:
BigDecimal('64.400000000000005684341886080801486968994140625')
#=> #<BigDecimal:7fd7cc04a0c8,'0.6440000000 0000005684 3418860808 0148696899 4140625E2',54(63)>
IMO, 64.4.to_d
should return just that.
Related Topics
What's the Difference Between Ruby'S Dup and Clone Methods
Ruby 1.9: Invalid Byte Sequence in Utf-8
Look Up All Descendants of a Class in Ruby
What Does the "===" Operator Do in Ruby
Ruby 2.0.0P0 Irb Warning: "Dl Is Deprecated, Please Use Fiddle"
Difference Between Include and Require in Ruby
When to Use Lambda, When to Use Proc.New
How to Avoid Running Activerecord Callbacks
How to Get the Name of the Calling Method
Connecting Rails 3.1 With Multiple Databases
How to Find and Return a Duplicate Value in Array
How to Download a Binary File Over Http