Round down float number - ruby-on-rails

I have the following float: 2.554 and I need to format as percentage using ruby/rails.
How to round down that float ?
I tried to use number_to_percentage but the value is displayed as 2.6 (round up)

You cant use the round method specifying the number of digits to round.
Sample
2.554.round(2)
=> 2.55
With the next variant you can force to round down if the third digit after comma is less than 5
2.555.round(2, half: :down)
=> 2.55

Related

Calculating a simple decimal in rails console using postgresql

Ok...I think I'm missing something very obvious here but haven't been able to google myself through this solution. I have two simple rails methods that calculate the number of up votes and down votes. They will always return a fraction because i'm trying to show a percentage (up_vote_count / votal_vote_count). I open the rails console and run the following:
y = #somespecificrecord
then...
y.up_vote_count
This returns 1 as is expected
y.down_vote_count
This returns 1 as is expected
y.total_vote_count
This returns 2 as is expected.
However, when I run in the console...
y.up_vote_count / y.total_vote_count
This returns 0 when it should return .50. I've been reading about floats/integers/decimals, etc and I do see this in the schema on the model i'm working from:
t.float "value", default: 0.0
Is this my problem?...and if so what do I have to do to allow myself to do a simple formula like the one above in rails console that will return the correct decimal rounded to 2 digits (i.e, .50 in this case above). I don't know if I want to run any migrations to change data types because this is a gem (& as a beginner I tend to stay away from customizing code from any gems I'm using). Is there another way? something small i'm missing hopefully?
UPDATE:
I'm learning decimals are slower than floats also, so is there any way to accomplish this with continuing to use t.float "value", default: 0.0
thanks for any help.
1 / 2 = 0.5
With integers this will round down to 0
You can get around this by casting the divisor to a float, forcing it to do division with floating point accuracy.
y.up_vote_count / y.total_vote_count.to_f
Float
Float objects represent inexact real numbers using the native
architecture's double-precision floating point representation.
Floating point has a different arithmetic and is an inexact number.
its important to know if you divide 2 hole numbers you are going to get a hole number.
if you are looking a decimal you should first convert your numbers to a decimal or a "float" like this
up_votes = y.up_vote_count.to_f
total_vote = y.down_vote_count.to_f
(up_votes / total_vote) * 100.0
I hope that this helps

Fixing number of digits after comma

I want to fix the number of digits after the comma (or decimal point) for a decimal result of a Cypher query:
match(n)
.
.
.
return(X)
How can I do this please?
As far as I know there is no way to round to a specific decimal precision so it you have to multiply to gross it up, round it and divide by the same number you multiplied by again to get back to the precision you desire.
Consider the following example to round to the nearest thousandth.
with 1.23456789 as dec_raw
return round(dec_num * 1000) / 1000 as dec_precision

How do I round a positive float up the next integer?

I need to round a positive float upwards to the nearest integer.
examples;
1.0 rounds up to 1
2.1 rounds up to 3
3.5 rounds up to 4
4.9 rounds up to 5
i.e. always round up.
Use the Ceil function from the Math unit. From the documentation:
Rounds variables up toward positive infinity.
Call Ceil (as in ceiling) to obtain the lowest integer greater than or
equal to X. The absolute value of X must be less than MaxInt. For
example:
Ceil(-2.8) = -2
Ceil(2.8) = 3
Ceil(-1.0) = -1
I cannot tell whether or not the behaviour of Ceil meets your expectations for negative input values, because you did not specify what to do there. However, if Ceil does not meet your expectations, it is easy enough to write a function to meet your needs, by combining Abs() and Ceil()
FindField('QTY').ASFLOAT := TRUNC(FindField('QTY').ASFLOAT) + 1
Works Fine

Show full decimal in Ruby

I'd like to print the full decimal value of a number in Ruby. I have this:
number = 0.00000254
number.round(8)
puts "Your number equals: " + number.to_s
The number will always be a maximum of eight places after the decimal and I want to always show them all. However, the above code only returns this:
=> Your number = 0.0
(The rounding is only my attempt to get the decimal places that far, I have no desire to round the number). How can I force Ruby to show up to eight places even when there are zeroes at the end like if the number was .00000100?
I just started learning the language last week so if you could use the example above in your answer, that would be great.
Thanks,
Matt
number = 0.00000254
puts "%.8f" % number
You can use number_with_precision from ActionView::Helpers::NumberHelpe.
> include ActionView::Helpers::NumberHelper
=> Object
> number_with_precision(0.00000254, precision: 8)
=> "0.00000254"

number_to_currency rounding precision wrong

I am very curious why Ruby render decimal with precision 2 inconsistently.
For example:
helper.number_to_currency 9.995
=> "$9.99"
whilst
helper.number_to_currency 10.995
=> "$11.00"...should it be "$10.99"?
It is a floating point precision error. I will probably submit a patch to fix this because I'm using number_to_currency on my website too.
Here's what's happening in more detail:
number_to_currency ends up just calling number_with_precision to get the number correctly formatted. number_with_precision immediately converts the number to a Float. Essentially, it comes down to this line in the Rails code:
# File actionpack/lib/action_view/helpers/number_helper.rb, line 280
rounded_number = BigDecimal.new((number * (10 ** precision)).to_s).round.to_f / 10 ** precision
The number you provide is multiplied by 100 before it is converted to BigDecimal. Look at this simple irb session:
irb(main):001:0> 9.995 * 100
=> 999.4999999999999
That number would obviously round down to 999, then it will be divided by 100 to give you 9.99.
The only workaround for this that I can think of for the moment is to do your own rounding before you pass in the number.
Looks like it is using "Round half to odd" rule.
So "1.5" gets rounded down to the nearest odd number (1) and 2.5 gets rounded up to the nearest odd number (3).
For a randomly distributed set of numbers to be rounded this form of rounding will consitently produce the smallest difference between the sum of unrounded numbers and the sum of rounded numbers.

Resources