printf with octal numbers

B

Brooks Davis

--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--
 
D

David Sletten

Brooks said:
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
 

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. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,564
Members
45,039
Latest member
CasimiraVa

Latest Threads

Top