ruby round off to two decimal place and keep zero [duplicate] - ruby-on-rails

This question already has answers here:
to_d to always return 2 decimals places in ruby
(5 answers)
Closed 7 years ago.
i want to round off a number upto two decimal place in ruby such that
(0.02 * 270187).round(2) is 5403.74 which is correct
but
(0.02 * 278290).round(2) is 5565.8 which is not consistent with previous one
i want to make it look like 5565.80
Please tell me how can i do it in ruby

This will do the trick:
> sprintf("%.2f",(0.02 * 270187))
#=> "5403.74"
> sprintf("%.2f",(0.02 * 278290))
#=> "5565.80"
> sprintf("%.2f",(0.02 * 270187)).to_f > 100 # If you plan to Compare something with result
#=> true
OR
> '%.2f' % (0.02 * 270187)
#=> "5403.74"
> '%.2f' % (0.02 * 278290)
#=> "5565.80"
Demo
Note: The result is always a string, but since you're rounding I assume you're doing it for presentation purposes anyway. sprintf can format any number almost any way you like. If you are planning to compare anything with this result then convert this string to float by adding .to_f at the end. Like this

You could do something like
include ActionView::Helpers::NumberHelper
number_with_precision(value, :precision => 2) # value.to_f if you have string
or like this
'%.2f' % your_value
Hope it helps!
Further you can read from here

Related

Rails round number [duplicate]

This question already has answers here:
A way to round Floats down
(11 answers)
Closed 6 years ago.
I have number num = 24.89808 and want to round it to 24.89
How can i do it?
i tried num.round(2) but it gives me 24.9 also number_to_currency=>24.90
If you are talking about rounding, 24.9 is by all means the correct result. Whether you are interested in ceiling it, here you go:
(24.89808 * 100).floor / 100.0
#⇒ "24.89"
First convert that into a decimal and then round it two two places,
Try this command,
num.to_d.round(2, :truncate).to_f
2.2.4 :040 > num = 24.89808
=> 24.89808
2.2.4 :041 > num.to_d.round(2,:truncate).to_f
=> 24.89

Ruby-on-rails evaluation of mathementical expression

In Ruby-on-rails, I am receiving input from a call to a XL macro(currently hard coded), which places a mathematical expression in the spreadsheet. If I call the macro I will receive a worksheet with an expression like this in one of the cells
x + ( 3 / 12)
In the R-O-R application I wish to take this expression and evaluate for different values of x.
row.each do |row|
y = row
end
I want to find the value of y for say example x = 2 ? Should I receive this expression as a literal ?
There is no built-in function to do this securely. You need a math parser and evaluator. You can write one yourself or you could use an existing one like Dentaku.
eval and gsub will get you most of the way there. Fire up irb:
(533)⚡️ irb
2.1.2 :001 > exp = 'x + (3 / 12)'
=> "x + (3 / 12)"
2.1.2 :002 > eval(exp.gsub(/x/, '25'))
=> 25
2.1.2 :003 > exp = 'x + (4.0 / 25.0) + 4'
=> "x + (4.0 / 25.0) + 4"
2.1.2 :004 > eval(exp.gsub(/x/, '25'))
=> 29.16
Notice the result of command 002. Ruby is assuming the 3 / 12 is integer math, so the result will be an integer, which is 0 in this case. In 003 floating point math occurs because the numbers are decimals. This aspect may be an issue you need to tackle more creatively, or just make sure your expressions conform to the type of math you need to occur.
Be aware of the security concerns with eval, you're executing Ruby code in there, so mean people may put mean things in there to try and execute it.
Why not write a one line function, as following:
def foo(x) x + (3 / 12) end
Now you can use this to calculate any value of x, for x = 2, you can do: foo(2) or foo 2.

Generating Random Fixed Decimal in Rails

I'm trying to generate random data in my rails application.
But I am having a problem with decimal amount. I get an error
saying bad value for range.
while $start < $max
$donation = Donation.new(member: Member.all.sample, amount: [BigDecimal('5.00')...BigDecimal('200.00')].sample,
date_give: Random.date_between(:today...Date.civil(2010,9,11)).to_date,
donation_reason: ['tithes','offering','undisclosed','building-fund'].sample )
$donation.save
$start +=1
end
If you want a random decimal between two numbers, sample isn't the way to go. Instead, do something like this:
random_value = (200.0 - 5.0) * rand() + 5
Two other suggestions:
1. if you've implemented this, great, but it doesn't look standard Random.date_between(:today...Date.civil(2010,9,11)).to_date
2. $variable means a global variable in Ruby, so you probably don't want that.
UPDATE --- way to really get random date
require 'date'
def random_date_between(first, second)
number_of_days = (first - second).abs
[first, second].min + rand(number_of_days)
end
random_date_between(Date.today, Date.civil(2010,9,11))
=> #<Date: 2012-05-15 ((2456063j,0s,0n),+0s,2299161j)>
random_date_between(Date.today, Date.civil(2010,9,11))
=> #<Date: 2011-04-13 ((2455665j,0s,0n),+0s,2299161j)>

How to count the number of decimal places in a Float?

I am using Ruby 1.8.7 and Rails 2.3.5.
If I have a float like 12.525, how can a get the number of digits past the decimal place? In this case I expect to get a '3' back.
Something like that, I guess:
n = 12.525
n.to_s.split('.').last.size
You should be very careful with what you want. Floating point numbers are excellent for scientific purposes and mostly work for daily use, but they fall apart pretty badly when you want to know something like "how many digits past the decimal place" -- if only because they have about 16 digits total, not all of which will contain accurate data for your computation. (Or, some libraries might actually throw away accurate data towards the end of the number when formatting a number for output, on the grounds that "rounded numbers are more friendly". Which, while often true, means it can be a bit dangerous to rely upon formatted output.)
If you can replace the standard floating point numbers with the BigDecimal class to provide arbitrary-precision floating point numbers, then you can inspect the "raw" number:
> require 'bigdecimal'
=> true
> def digits_after_decimal_point(f)
> sign, digits, base, exponent = f.split
> return digits.length - exponent
> end
> l = %w{1.0, 1.1, 1000000000.1, 1.0000000001}
=> ["1.0,", "1.1,", "1000000000.1,", "1.0000000001"]
> list = l.map { |n| BigDecimal(n) }
=> [#<BigDecimal:7f7a56aa8f70,'0.1E1',9(18)>, #<BigDecimal:7f7a56aa8ef8,'0.11E1',18(18)>, #<BigDecimal:7f7a56aa8ea8,'0.1000000000 1E10',27(27)>, #<BigDecimal:7f7a56aa8e58,'0.1000000000 1E1',27(27)>]
> list.map { |i| digits_after_decimal_point(i) }
=> [0, 1, 1, 10]
Of course, if moving to BigDecimal makes your application too slow or is patently too powerful for what you need, this might overly complicate your code for no real benefit. You'll have to decide what is most important for your application.
Here is a very simple approach. Keep track of how many times you have to multiple the number by 10 before it equals its equivalent integer:
def decimals(a)
num = 0
while(a != a.to_i)
num += 1
a *= 10
end
num
end
decimals(1.234) # -> 3
decimals(10/3.0) # -> 16
Like This:
theFloat.to_s.split(".")[1].length
It is not very pretty, but you can insert it as a method for Float:
class Float
def decimalPlaces
self.to_s.split(".")[1].length
end
end
Can you subtract the floor and then just count how many characters left?
(12.525 -( 12.52­5.floor )).to­_s.length-­2
=> 3
edit: nope this doesnt work for a bunch of reasons, negatives and 0.99999 issues
Olexandr's answer doesn't work for integer. Can try the following:
def decimals(num)
if num
arr = num.to_s.split('.')
case arr.size
when 1
0
when 2
arr.last.size
else
nil
end
else
nil
end
end
You can use this approach
def digits_after_decimal_point(n)
splitted = n.to_s.split(".")
if splitted.count > 1
return 0 if splitted[1].to_f == 0
return splitted[1].length
else
return 0
end
end
# Examples
digits_after_decimal_point("1") #=> 0
digits_after_decimal_point("1.0") #=> 0
digits_after_decimal_point("1.01") #=> 2
digits_after_decimal_point("1.00000") #=> 0
digits_after_decimal_point("1.000001") #=> 6
digits_after_decimal_point(nil) #=> 0

How to cap and round number in ruby

I would like to "cap" a number in Ruby (on Rails).
For instance, I have, as a result of a function, a float but I need an int.
I have very specific instructions, here are some examples:
If I get 1.5 I want 2 but if I get 2.0 I want 2 (and not 3)
Doing number.round(0) + 1 won't work.
I could write a function to do this but I am sure one already exists.
If, nevertheless, it does not exist, where should I create my cap function?
Try ceil:
1.5.ceil => 2
2.0.ceil => 2
How about number.ceil?
This returns the smallest Integer greater than or equal to number.
Be careful if you are using this with negative numbers, make sure it does what you expect:
1.5.ceil #=> 2
2.0.ceil #=> 2
(-1.5).ceil #=> -1
(-2.0).ceil #=> -2
.ceil is good, but remember, even smallest value in float will cause this:
a = 17.00000000000002
17.0
a.ceil
18
Use Numeric#ceil:
irb(main):001:0> 1.5.ceil
=> 2
irb(main):002:0> 2.0.ceil
=> 2
irb(main):003:0> 1.ceil
=> 1
float.ceil is what you want for positive numbers. Be sure to consider the behavior for negative numbers. That is, do you want -1.5 to "cap" to -1 or -2?

Resources