printf with octal numbers

Discussion in 'Ruby' started by Brooks Davis, Jan 26, 2005.

  1. Brooks Davis

    Brooks Davis Guest

    --AqsLC8rIMeq19msA
    Content-Type: text/plain; charset=us-ascii
    Content-Disposition: inline
    Content-Transfer-Encoding: quoted-printable

    The behavior of sprintf("%d", str) is not what I would expect. If str
    begins with a '0', for example "01", it is treated as an octal number.
    This seem odd because I would expect the following two lines to be the
    same:

    sprintf("%d", str)
    sprintf("%d", str.to_i)

    This is not the case:

    irb(main):006:0> str=3D"08"
    =3D> "08"
    irb(main):007:0> sprintf("%d", str)
    ArgumentError: invalid value for Integer: "08"
    from (irb):7:in `sprintf'
    from (irb):7
    irb(main):008:0> sprintf("%d", str.to_i)
    =3D> "8"
    irb(main):009:0> str=3D"010"
    =3D> "010"
    irb(main):010:0> sprintf("%d", str)
    =3D> "8"
    irb(main):011:0> sprintf("%d", str.to_i)
    =3D> "10"

    The seems to violate POLA. In my case it was quite astonishing because
    I had a script where I parse strings like "r01rpc2" to find the rack and
    power controller number from a string. When I added my eighth rack, the
    script stopped working after several years of operation. Is this
    behavior intended? The documentation on rubycentral doesn't really say
    one way or another.

    In case it matters, my ruby version is:

    [12:15pm] brooks@minya (~/working/cluster/power): ruby -v
    ruby 1.8.2 (2004-07-29) [i386-freebsd6]

    Thanks,
    Brooks

    --=20
    Any statement of the form "X is the one, true Y" is FALSE.
    PGP fingerprint 655D 519C 26A7 82E7 2529 9BF0 5D8E 8BE9 F238 1AD4

    --AqsLC8rIMeq19msA
    Content-Type: application/pgp-signature
    Content-Disposition: inline

    -----BEGIN PGP SIGNATURE-----
    Version: GnuPG v1.2.1 (GNU/Linux)

    iD8DBQFB+Ck7XY6L6fI4GtQRAr1jAKCRKwb88oqvxodvspsshxHYfdBUNACg3VlP
    ndBgPr5C27CZqFGMka/Y+mw=
    =UnMH
    -----END PGP SIGNATURE-----

    --AqsLC8rIMeq19msA--
     
    Brooks Davis, Jan 26, 2005
    #1
    1. Advertising

  2. Brooks Davis wrote:

    > The behavior of sprintf("%d", str) is not what I would expect. If str
    > begins with a '0', for example "01", it is treated as an octal number.
    > This seem odd because I would expect the following two lines to be the
    > same:
    >
    > sprintf("%d", str)
    > sprintf("%d", str.to_i)
    >
    > This is not the case:
    >
    > irb(main):006:0> str="08"
    > => "08"
    > irb(main):007:0> sprintf("%d", str)
    > ArgumentError: invalid value for Integer: "08"
    > from (irb):7:in `sprintf'
    > from (irb):7
    > irb(main):008:0> sprintf("%d", str.to_i)
    > => "8"
    > irb(main):009:0> str="010"
    > => "010"
    > irb(main):010:0> sprintf("%d", str)
    > => "8"
    > irb(main):011:0> sprintf("%d", str.to_i)
    > => "10"
    >
    > The seems to violate POLA. In my case it was quite astonishing because
    > I had a script where I parse strings like "r01rpc2" to find the rack and
    > power controller number from a string. When I added my eighth rack, the
    > script stopped working after several years of operation. Is this
    > behavior intended? The documentation on rubycentral doesn't really say
    > one way or another.
    >



    This behavior is a little odd. The documentation for String#to_i (A bit
    out of date here:
    http://www.rubycentral.com/book/ref_c_string.html#String.to_i) says that
    if no arg is passed to to_i(), then the default base is 10. The string
    is then evaluated in that base, so leading 0's are ignored. If a base of
    0 is given, then to_i() looks for leading '0', '0b', '0o', '0d', or '0x'
    to determine the base. The method never raises an exception, but returns
    0 instead when no valid number is found.
    Thus:
    irb(main):255:0> "08".to_i
    => 8
    irb(main):256:0> "08".to_i(0) #Viewed as octal. '8' is invalid digit.
    => 0
    irb(main):257:0> "07".to_i(0) #Octal
    => 7
    irb(main):258:0> "7".to_i(0) #Decimal
    => 7


    sprintf() appears to interpret numeric strings differently--in line with
    the rules for numeric literals in Ruby:
    irb(main):261:0> 08
    SyntaxError: compile error
    (irb):261: Illegal octal digit
    from (irb):261
    irb(main):262:0> sprintf("%d", "08")
    ArgumentError: invalid value for Integer: "08"
    from (irb):262:in `sprintf'
    from (irb):262
    irb(main):263:0> sprintf("%d", "0d8")
    => "8"

    I would suggest you stick with explicitly calling to_i.

    David Sletten
     
    David Sletten, Jan 27, 2005
    #2
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. James Stroud

    Recursive Property of Octal Numbers

    James Stroud, Sep 30, 2005, in forum: Python
    Replies:
    3
    Views:
    256
    Tim Roberts
    Oct 4, 2005
  2. ben
    Replies:
    4
    Views:
    624
    Martin Ambuhl
    Jun 26, 2004
  3. whatluo

    (void) printf vs printf

    whatluo, May 26, 2005, in forum: C Programming
    Replies:
    29
    Views:
    1,252
  4. azza

    printf affects following printf/s

    azza, Oct 17, 2010, in forum: C Programming
    Replies:
    0
    Views:
    435
  5. guru
    Replies:
    8
    Views:
    286
Loading...

Share This Page