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.

    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
    #1
    1. Advertisements

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

    Hope that helps.

    James Edward Gray II
     
    James Edward Gray II, Oct 31, 2005
    #2
    1. Advertisements

  3. i.v.r.

    i.v.r. Guest

    That was fast! Thanks a lot.
     
    i.v.r., Oct 31, 2005
    #3
  4. ------=_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
    #4
  5. Hi --

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


    David
     
    David A. Black, Nov 1, 2005
    #5
  6. Hmm, it's certainly not Ruby length...

    James Edward Gray II
     
    James Edward Gray II, Nov 1, 2005
    #6
  7. i.v.r.

    Ara.T.Howard Guest

    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
    #7
  8. --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
    #8
  9. 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
    #9
  10. 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
    #10
  11. i.v.r.

    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
    #11
  12. In that case...
    "%.2f" % 1.012345
    => "1.01"
     
    Logan Capaldo, Nov 2, 2005
    #12
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.