# Newbie: How to format a number to always show two decimals?

Discussion in 'Ruby' started by i.v.r., Oct 31, 2005.

1. ### i.v.r.Guest

Hi,

This seems like a simple task, yet I've been unable to accomplish it.
Somewhere I read you could do:

num.round(2).to_s("F")

But that is not working, as the round method doesn't accept any parameters.

Could someone help me figure this out?

Thanks!

Ivan V.

i.v.r., Oct 31, 2005

2. ### James Edward Gray IIGuest

?> "%.2f" % 1.012345
=> "1.01"

Hope that helps.

James Edward Gray II

James Edward Gray II, Oct 31, 2005

3. ### i.v.r.Guest

That was fast! Thanks a lot.

i.v.r., Oct 31, 2005
4. ### Harold HausmanGuest

------=_Part_9875_4065111.1130804492474
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

Alternatively there's this code from Phrogz's library (
http://phrogz.net/rubylibs) which to me is more rubyish than sprintf.
Everytime you use sprintf, God kills a kitten.

-Harold

#Code Follows:

class Numeric
# Rounds to the specified number of decimal places, returning a string
value.
#
# (1.234).round_to(2) =3D> '1.23'
# (-1.234).round_to(2) =3D> '-1.23'
# (-0.007).round_to(2) =3D> '-0.01'
# (-0.007).round_to(1) =3D> '0.0'
def round_to(decimals)
if self<0 then
s=3D'-';
x=3D-self;
else
s=3D'';
x=3Dself;
end
if x>=3D1.0e15 then
m=3Dx.to_s;
else
m=3D(x*10**decimals).round.to_s
if (decimals!=3D0) then
k=3Dm.length;
if k<=3Ddecimals then
z=3D'000000000000000'[0..(decimals-k)]
m=3Dz+m;
k=3Ddecimals+1;
end
m.insert(k-decimals,'.');
end
end
s=3D'' if (/^0\.0*\$/=3D~m);
s+m;
end
end

------=_Part_9875_4065111.1130804492474--

Harold Hausman, Nov 1, 2005
5. ### David A. BlackGuest

Hi --

Aside to Phrogz: is that left over from a game of code golf?? David

David A. Black, Nov 1, 2005
6. ### James Edward Gray IIGuest

Hmm, it's certainly not Ruby length...

James Edward Gray II

James Edward Gray II, Nov 1, 2005
7. ### Ara.T.HowardGuest

that quote is absolutely beautiful - though i __much__ prefer printf to cout
;-)
-a
--
===============================================================================
| email :: ara [dot] t [dot] howard [at] noaa [dot] gov
| phone :: 303.497.6469
| anything that contradicts experience and logic should be abandoned.
| -- h.h. the 14th dalai lama
===============================================================================

Ara.T.Howard, Nov 1, 2005
8. ### Gavin KistnerGuest

--Apple-Mail-4-77238386
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain;
charset=MACINTOSH;
delsp=yes;
format=flowed

LOL. No, before I grokked sprintf, I needed the round_to =20
functionality. That's a port of the Number.toFixed algorithm from =20
section 15.7.4.5 of the ECMAScript (ECMA-262) specs:

15.7.4.5 Number.prototype.toFixed (fractionDigits)
Return a string containing the number represented in fixed-point =20
notation with fractionDigits digits after the decimal point. If =20
fractionDigits is undefined, 0 is assumed. Specifically, perform the =20
following steps:

1. Let =C4 be ToInteger(fractionDigits). (If fractionDigits is =20
undefined, this step produces the value 0).
2. If =C4 < 0 or =C4 > 20, t hrow a RangeError exception.
3. Let x be this number value.
4. If x is NaN, return the string "NaN".
5. Let s be t he empty string.
6. I f x =B3 0, go to step 9.
7. Let s be "-".
8. Let x =3D =D0x.
9. I f x =B3 10^21, let m =3D ToString(x) and go to step 20.
10. Let n be an integer for which the exact mathematical value of n =D6 =20=

10^=C4 =D0 x is as close to zero as possible. If there are two such n, =20=

pick t he larger n.
11. I f n =3D 0, let m be the string "0". Otherwise, let m be the =20
string consisting of the digits of the decimal representation of n =20
(in order, with no leading zeroes).
12. If =C4 =3D 0, go to step 20.
13. Let k be the number of characters in m.
14. If k > =C4, go to step 18.
15. Let z be the string consisting of =C4 +1=D0k occurrences of the =20
character =D40=D5.
16. Let m be the concatenation of strings z and m.
17. Let k =3D =C4 + 1.
18. Let a be the first k=D0=C4 characters of m, and let b be the =20
remaining =C4 characters of m.
19. Let m be the concatenation of the three strings a, ".", and b.
20. Return the concatenation of the strings s and m.

--Apple-Mail-4-77238386--

Gavin Kistner, Nov 1, 2005
9. ### David A. BlackGuest

Hi --

Interesting pedigree.

It was the semi-colons and the vacuum-packed syntax that made me think
it might be a multi-line split-out of a former golf entry David

David A. Black, Nov 1, 2005
10. ### Gavin KistnerGuest

Ah, no. Upon reflection, those are because the ruby code is actually
a port of my JavaScript version of that algorithm. Microsoft's own
implementation of Number.toFixed did not (at some point, perhaps
currently) conform to that algorithm (and other JS engines did not at
some point support that method, despite it being part of the spec) so
I wrote my own JS-only port to patch bad engines as needed. When it
came time to for the Ruby version, a bit of syntax conversion seems
to be all I did.

At the point in my life when I wrote the JS version, I was very into
very terse formatting. Whitespace seemed to be at a premium during
that dark period. Gavin Kistner, Nov 1, 2005
11. ### i.v.r.Guest

What's wrong with sprintf? I don't see how sprintf is evil versus the
long procedure you detailed, but what do I know... I'm just a BASIC
programmer, LOL.

Ivan

i.v.r., Nov 1, 2005
12. ### Logan CapaldoGuest

In that case...
"%.2f" % 1.012345
=> "1.01"

Logan Capaldo, Nov 2, 2005