When I round of 12121.232323 to 2 digit decimal point like below
p 12121.232323.round(2)
it is printing
12121.23
But when I try to round()
211211.00000.round(2)
it's printing
211211.0
But I want
211211.00
How do I do that?
'%.2f' % 12121.232323
or
include ActionView::Helpers::NumberHelper
number_with_precision(value, :precision => 2)
What you seek is not exactly rounding but formatting.
You can select your float formatting like this:
p "%.2f" % 12121.0000
where the %.2f part means "show 2 decimal points"
Related
I need to do integer division. I expect the following to return 2 instead of the actual 1:
187 / 100 # => 1
This:
(187.to_f / 100).round # => 2
will work, but does't seem elegant as a solution. Isn't there an integer-only operator that does 187 / 100 = 2?
EDIT
I'll be clearer on my use case since I keep getting down-voted:
I need to calculate taxes on a price. All my prices are in cents. There is nothing below 1 cent in the accountability world so I need to make sure all my prices are integers (those people checking taxes don't like mistakes... really!)
But on the other hand, the tax rate is 19%.
So I wanted to find the best way to write:
def tax_price(price)
price * TAX_RATE / 100
end
that surely returns an integer, without any floating side effect.
I was afraid of going to the floating world because it has very weird side-effects on number representation like:
Ruby strange issue with floating point multiplication
ruby floating point errors
So I found it safer to stay in the integer or the fractional world, hence my question.
You can do it while remaining in the integer world as follows:
def round_div(x,y)
(x + y / 2) / y
end
If you prefer, you could monkey-patch Fixnum with a variant of this:
class Fixnum
def round_div(divisor)
(self + divisor / 2) / divisor
end
end
187.round_div(100) # => 2
No – (a.to_f / b.to_f).round is the canonical way to do it. The behavior of integer / integer is (for example) defined in the C standard as "discarding the remainder" (see http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf page 82) and ruby uses the native C function.
This is a less know method, Numeric#fdiv
You use it like this : 187.fdiv(100).round
Not sure, but this might be what you have in mind.
q, r = 187.divmod(100)
q + (100 > r * 2 ? 0 : 1) # => 2
This should work for you :
Use syntax like this.
(number.to_f/another_number).round
Example:
(18.to_f/5).round
As #MattW already answer (+1), you'd have to cast your integers to floats.
The only other way that is less distracting can be to add .0 to your integer:
(187.0 / 100).round
However, usually we don't operate on concrete integers but variables and this method would be no use.
After some thoughts, I could:
have used BigDecimals but it feels like a bazooka to kill a bird
or I can use a custom method that wouldn't use floating division within the process, as #sawa suggests
def rounded_integer_div(numerator, denominator)
q, r = numerator.divmod(denominator)
q + (100 > r * 2 ? 0 : 1)
end
If what you want is to actually only increase the result by 1 if there's any remainder (e.g. for counting paging/batching), you can use the '%' (modula operation) for remainders checking.
# to add 1 if it's not an even division
a = 187
b = 100
result = a / b #=> 1
result += 1 if (a % b).positive?
#=> 2
# or in one line
result = (a / b) + ((a % b).zero? ? 0 : 1)
Is it posible to round the base of an of a number in E-notation: i.e.
4.454554e-63 ==> 4e-63
I know I can do it as follows, but I was wondering if anyone knows of an elegant way of doing it...
s = '4.454554e-63'
s.scan((/^(\d*).\d*e-(\d*)/) do |n, p|
puts "#{n.to_i}" + "e-" + "#{p}"
end
Many Thanks,
You may use % operator:
"%.0e" % s
The syntax of a format sequence:
%[flags][width][.precision]type
Field | Float Format
------+--------------------------------------------------------------
e | Convert floating point argument into exponential notation
| with one digit before the decimal point as [-]d.dddddde[+-]dd.
| The precision specifies the number of digits after the decimal
| point (defaulting to six).
i.e. precision should be 0 in your case
Okay..
I have these float numbers in a ruby array :-)
12.321912389
122.438783
345.23242444
89.37827383
I want to convert these numbers to 6 digits numbers without losing float property.
something like :-)
12.3219
122.438
345.232
89.3782
Which function can help me? sorry if this question is very naive to you :-)
You can play with sprintf "g" format, what you need is 6 significant digits:
(0..6).map{|i| '%.6g' % (10.0**i / 3)}
=> ["0.333333", "3.33333", "33.3333", "333.333", "3333.33", "33333.3", "333333"]
This is very stupid (and slow), but it works (assuming numbers contain decimal point):
numbers = [12.321912389, 122.438783, 345.23242444, 89.37827383]
numbers.map! { |num| num.to_s[0..6].to_f }
p numbers #=> [12.3219, 122.438, 345.232, 89.3782]
This seems horrible inefficient. Can someone give me a better Ruby way.
def round_value
x = (self.value*10).round/10.0 # rounds to two decimal places
r = x.modulo(x.floor) # finds remainder
f = x.floor
self.value = case
when r.between?(0, 0.25)
f
when r.between?(0.26, 0.75)
f+0.5
when r.between?(0.76, 0.99)
f+1.0
end
end
class Float
def round_point5
(self * 2).round / 2.0
end
end
A classic problem: this means you're doing integer rounding with a different radix. You can replace '2' with any other number.
Multiply the number by two.
round to whole number.
Divide by two.
(x * 2.0).round / 2.0
In a generalized form, you multiply by the number of notches you want per whole number (say round to .2 is five notches per whole value). Then round; then divide by the same value.
(x * notches).round / notches
You can accomplish this with a modulo operator too.
(x + (0.05 - (x % 0.05))).round(2)
If x = 1234.56, this will return 1234.6
I stumbled upon this answer because I am writing a Ruby-based calculator and it used Ruby's Money library to do all the financial calculations. Ruby Money objects do not have the same rounding functions that an Integer or Float does, but they can return the remainder (e.g. modulo, %).
Hence, using Ruby Money you can round a Money object to the nearest $25 with the following:
x + (Money.new(2500) - (x % Money.new(2500)))
Here, if x = $1234.45 (<#Money fractional:123445 currency:USD>), then it will return $1250.00 (#
NOTE: There's no need to round with Ruby Money objects since that library takes care of it for you!
I understand due to the inexact representation of floating points, the following code 'feels' inconsistent.
"%.1f" % 1.14 # => 1.1
"%.1f" % 1.15 # => 1.1
"%.1f" % 1.16 # => 1.2
"%.0f" % 1.4 # => 1
"%.0f" % 1.5 # => 2
"%.0f" % 1.6 # => 2
However, is there an easy way of doing consistent floating points rounding by 5? One way might be to do string manipulation explicitly. Is there an easier way or existent library?
If you want decimal precision, use BigDecimal instead of floats.
Edit: You will have to manually round the number to the desired length before passing it to %, otherwise it gets converted to a normal float before being rounded.
"%.1f" % BigDecimal('1.15').round(1) => "1.2"
"%.0f" % BigDecimal('1.5').round(0) => "2"
Just add a tiny pertubation, to ensure things that are just under 0.5 in floating-point become just over.
For example,
x = 1.15
"%.1f" % (1.000001*x) # include correction for imprecise floating-point.
this will be enough to deal with the formatting problems, while very unlikely to cause a relevant error.
also: an obvious follow-on to my earlier question here, which is fine, but included for completeness.
The function roundthis() in this example shows how to round numbers in a controllable, consistent way. Note the small fudge value. Try running this example without the fudge to see what happens.
def roundthis(x, m)
return (x/m+0.50001).floor*m
end
for x in [1.14, 1.15, 1.16]
print "#{x} #{roundthis(x, 0.1)} \n"
end
for x in [1.4, 1.5, 1.6]
print "#{x} #{roundthis(x, 1.0)} \n"
end
This, put into a file named roundtest.rb and executed prints
bash> ruby roundtest.rb
1.14 1.1
1.15 1.2
1.16 1.2
1.4 1.0
1.5 2.0
1.6 2.0
Note the ease of rounding to the nearest 2, 15, 0.005, or whatever.
Multiply by 100, then round, then divide by 100:
(1.15 * 100).round / 100.0 # => 1.15
It's not exactly elegant, but it avoids using strings.