Formatting a float to a minimum number of decimal places - ruby-on-rails

I'm storing a decimal in rails and I need to have it display as a currency as such:
11.1230 => "$11.123"
11.1000 => "$11.10"
11.0100 => "$11.01"
11.1234 => "$11.1234"
Any easy way to do this?

def pad_number( number, min_decimals=2 )
s = "%g" % number
decimals = (s[/\.(\d+)/,1] || "").length
s << "." if decimals == 0
s << "0"*[0,min_decimals-decimals].max
end
puts [ 11.123, 11.1, 11.01, 11.1234, 11 ].map{ |n| pad_number(n) }
#=> 11.123
#=> 11.10
#=> 11.01
#=> 11.1234
#=> 11.00

Edit: Looks like this is Rails 3 specific, as Rails 2's number_with_precision method doesn't include the strip_insignificant_zeros option:
You can pass some options to number_to_currency (a standard Rails helper):
number_to_currency(11.1230, :precision => 10, :strip_insignificant_zeros => true)
# => "$11.123"
You need to provide a precision in order for the strip_insignificant_zeros option to work, though, otherwise the underlying number_with_precision method never gets called.

If you want to store as a float, you can use the number_to_currency(value) method in yours views for printing something that looks like $.
Correct me if I'm wrong (as I've rarely dealt with currency) but I think the conventional wisdom is to store dollar values as integers. That way you won't have to deal with funky float math.

So, convert it to three decimal fraction digits and then remove the final one if and only if it's a zero.
s.sub(/0$/, '')

Related

Ruby/Rails - Converting an integer into a float excluding existing zeros

There must be a simple way to achieve this, I have an DB field containing an integer and I want to reformat it into a float to display.
As an integer my value looks like 6500 and I want it to display as 65.00
Within my model I have attempted to achieve this by creating the following method
def get_payment_amount_as_number
amount = self.payment_amount
return '%.02f' % self.payment_amount.to_f
end
Which results in the following being displayed: 6500.00
What would the best approach be to either strip the initial zeroes or to simply insert a decimal point?
Whilst I imagine this a ruby related question, I am not sure if rails has a handy helper already in place?
Thank you.
You could divide the number by 100:
payment_amount = 6595
'%.02f' % payment_amount.fdiv(100)
#=> "65.95"
'%.02f' % (payment_amount / 100.0)
#=> "65.95"
Or you could convert the number to a string and insert a decimal point:
payment_amount.to_s.rjust(3, '0').insert(-3, '.')
#=> "65.95"
Rails also provides several helpers to format numbers:
number_to_currency(65.95)
#=> "$65.95"
number_to_currency(1000)
#=> "$1,000.00"
And you might want to take a look at the money-rails gem which provides a mapping from cents to money objects.
You do this simply ...
def get_payment_amount_as_number
amount = self.payment_amount / 100
#to convert amount to float
amount.to_f
end
I find another one
amount = self.payment_amount
# => 6500
ans = '%.2f' % (amount/100)
# => "65.00"
int_value = 6500
float_value = float_value = '%.2f' % (int_value / 100.0)
puts int_value: int_value, float_value: float_value
it's all!

How to add decimal place to last two positions in string? Rails 4

I am trying to convert the string 1009 to become $10.09. I have been looking at the documentation for NumberHelpers for about 15 minutes now and am a bit surprised that I did not find any methods that can add a decimal point delimiter . before the last two positions of a string or integer.
At first, I tried:
number_to_currency("1009", :unit => "$")
# => $1,009.00
then I tried using:
number_to_currency("1009", :unit => "$", :precision => 0)
# => $1,009
which only removes digits after the decimal place, but does not shift the decimal place itself. As well, adding -2 as the precision argument throws ArgumentError.
I know this is possible to do with a few lines of JavaScript but I was looking for a more a pure Rails approach, if any.
How would someone be able to accomplish this?
You could just divide the number with 100. It's simple and it works. I guess you are converting cents to USD, I don't think there's any other way around it.
number_to_currency("1009".to_f / 100, :unit => "$")
You could also write a helper for this, something like...
def cents_to_usd(amount)
number_to_currency(amount.to_f / 100, :unit => "$")
end
So that it looks nicer in your views.

to_d to always return 2 decimals places in ruby

I'm dealing with currencies and I want to round down the number to 2 decimal places. Even if the number is 500.0, I would like it to be 500.00 to be consistent. When I do "500.00".to_d it converts it to 500.0.
Whats a good way of changing this behavior? I also use this method to round down to 2 digits and make sure it always has 2 decimals.
def self.round_down(x, n=2)
s = x.to_s
l = s.index('.') ? s.index('.') + 1 + n : s.length
s = s[0, l]
s = s.index('.') ? s.length - (s.index('.') + 1) == 1 ? s << '0' : s : s << '.00'
s.to_f
end
In addition to mcfinnigan's answer, you can also use the following to get 2 decimal places
'%.2f' % 500 # "500.00"
This use case is known as the string format operator
Since you are using Rails and this seems to be related to a view, there's number_with_precision:
number_with_precision(500, precision: 2)
#=> "500.00"
I18n.locale = :de
number_with_precision(500, precision: 2)
#=> "500,00"
For currencies I'd suggest number_to_currency:
number_to_currency(500)
#=> "$500.00"
Here's a hint. 500.00 is a representation of the number 500.0
Specifically, sprintf will help you:
irb(main):004:0> sprintf "%.2f", 500.0
=> "500.00"
Do not use floating point numbers to represent money. See this question for a good overview of why this is a bad idea.
Instead, store monetary values as integers (representing cents), or have a look at the money gem that provides lots of useful functionality for dealing with such values.
There was a requirement to round DOWN.
Most other answers round 500.016 UP to 500.02
Try:
def self.round_down(x, n = 2)
"%.#{n}f" % x.to_d.truncate(n)
end
irb(main):024:0> x=500.0; '%.2f' % x.to_d.truncate(2)
=> "500.00"
irb(main):025:0> x=500.016; '%.2f' % x.to_d.truncate(2)
=> "500.01"

number_to_human with currency

I am using number_to_human to print 4 Million. I was wondering if there is a method that will add the $ to the front of the number?
I run into issues when I have a negative number.
If I just throw a $ in front I will get $-4 Million they want -$4 Million
It's builtin Rails:
number_to_currency(number_to_human(-4000000))
# => "-$4 Million"
The big advantage in using convention is that, when you need i18n, you just have to pass the locale:
number_to_currency(number_to_human(-4000000), locale: 'en-EU')
# => "-4 Million €"
Its interesting thing and If It would help to anybody:
How to Present thousands as "K", millions as "M" in ruby for that,
just follow the steps
Include NumberHelper in controller at top
include ActionView::Helpers::NumberHelper
Use this number_to_human Helper and pass the value, This will convert the value
<%= number_to_human(5223654) %>
Paste this code in en.yml to get it working
en:
number:
human:
decimal_units:
format: "%n%u"
units:
unit: ""
thousand: K
million: M
billion: B
trillion: T
quadrillion: Q
There must be better ways. however, here is a quick hack
amount = -4000000
if amount < 0
human = "-$#{number_to_human(amount.abs)}"
else
human = "$#{number_to_human(amount)}"
end
#apneadiving shows the real simple ways.

Ruby: Strip significant digits from number?

Suppose I have the number 1.29999. I want to just have 1.2 without the trailing 9s. Note, I don't want it to round to 1.3. How do I do this? I know there's the number helper, but I can't seem to get this working outside of a view. Any ideas?
For instance, number_with_precision 111.2345, :precision => 2 does not work if I just put it in a normal model function.
Thanks!
Another approach is to multiply by 100, truncate, then divide by 100.0:
$ irb --simple-prompt
>> (1.29999999*100).truncate/100.0
=> 1.29
Making it a method:
>> def truncate_to_two (x)
>> (x * 100).truncate/100.0
>> end
=> nil
>> truncate_to_two 6342.899
=> 6342.89
>> truncate_to_two -322.11892
=> -322.11
>> truncate_to_two 244.9342
=> 244.93
It's rudimentary, but you can do use string manipulation instead of math to do it. Example:
x = 1.29999
truncated = x.to_s.match(/(\d+\.\d{2})/)[0] # assumes the format "n.nn" with 2 or more digits of precision; the regex can be expanded to handle more cases
You can always include ActionView::Helpers::NumberHelper in your model to get access to the helpers.

Resources