Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number
 
PerlMonks  

Why are hex numbers inside strings extrapolating to numbers (incorrectly)?

by Anonymous Monk
on Feb 26, 2001 at 13:36 UTC ( #60834=perlquestion: print w/replies, xml ) Need Help??

Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

when i try to do print("0x30"+0); at home, perl says 1.5, while at work it says 48. i was using perl 5.6.0 in both cases and in both cases i was expecting to get 0. i tried it with perl 5.005_03 and the result was '1.5' again. print("030"+0); prints 30, not 24. with warnings on it even gives the 'non-numeric' warning, but then extrapolates it to number anyway. i even somehow can understand the 0x30 -> 48, but 0x30 -> 1.5 is far beyond my comprehension. print("0x37"+0,"\n"); gives the even more surprising result 1.71875. can somebody shed some light?

Replies are listed 'Best First'.
Re: Why are hex numbers inside strings extrapolating to numbers (incorrectly)?
by lanzz (Acolyte) on Feb 26, 2001 at 15:10 UTC

    here are the details:

    i have four different machines (all linux, all i686). two of them are running perl 5.6.0, the other two 5.005.

    i run the following test on all machines:

    perl -e 'print("0x30"+0,"\n")'

    here are the results:

    first machine (5.6.0): 1.5
    second machine (5.6.0): 48
    third machine (5.005): 48
    fourth machine (5.005): 1.5

    the second and third machine always evaluate the expression to whatever the decimal value of the hex number in the string is. the first and fourh evaluate to a fractional number.

    here is a test script i ran on one of the 'fractional' machines:

    #!/usr/bin/perl for ($i=1; $i<64; $i++) { print(sprintf("%02X: ",$i),("0x".sprintf("%X",$i))+0,"\n"); }

    here is the output:

    01: 1 02: 1 03: 1.5 04: 1 05: 1.25 06: 1.5 07: 1.75 08: 1 09: 1.125 0A: 1.25 0B: 1.375 0C: 1.5 0D: 1.625 0E: 1.75 0F: 1.875 10: 1 11: 1.0625 12: 1.125 13: 1.1875 14: 1.25 15: 1.3125 16: 1.375 17: 1.4375 18: 1.5 19: 1.5625 1A: 1.625 1B: 1.6875 1C: 1.75 1D: 1.8125 1E: 1.875 1F: 1.9375 20: 1 21: 1.03125 22: 1.0625 23: 1.09375 24: 1.125 25: 1.15625 26: 1.1875 27: 1.21875 28: 1.25 29: 1.28125 2A: 1.3125 2B: 1.34375 2C: 1.375 2D: 1.40625 2E: 1.4375 2F: 1.46875 30: 1.5 31: 1.53125 32: 1.5625 33: 1.59375 34: 1.625 35: 1.65625 36: 1.6875 37: 1.71875 38: 1.75 39: 1.78125 3A: 1.8125 3B: 1.84375 3C: 1.875 3D: 1.90625 3E: 1.9375 3F: 1.96875

    now what i need is an explanation :)

      I get 0 for all of them. (I'm running ActivePerl 5.6.0 on Win32)
(tye)Re: Why are hex numbers inside strings extrapolating to numbers (incorrectly)?
by tye (Sage) on Feb 26, 2001 at 21:07 UTC

    You don't mention the operating system (and C run-time libraries) used with these different machines. It appears to me that you've got a C run-time library that has an "extended" atof() (or whatever you built Perl to use to convert strings to numbers) that, for strings that start with "0x", converts the hex value into the mantissa of the resulting floating point number. I wonder what you have to add to the string to specify the exponent.

    Please give us the details on OS and C RTL versions and the config options related to number conversion that were used to build Perl. I also think a bug report to p5p is in order. Run perlbug to generate one of these.

            - tye (but my friends call me "Tye")
Re: Why are hex numbers inside strings extrapolating to numbers (incorrectly)?
by Corion (Pope) on Feb 26, 2001 at 21:02 UTC

    I also did run the tests under some configurations, and was able to reproduce some results :

    Linux x86 box : corion@samson > perl -v This is perl, version 5.005_02 built for i586-linux blah blah corion@samson >perl -w test.pl Argument "0x1" isn't numeric in add at test.pl line 4. 01: 1 Argument "0x2" isn't numeric in add at test.pl line 4. 02: 1 Argument "0x3" isn't numeric in add at test.pl line 4. 03: 1.5 Argument "0x4" isn't numeric in add at test.pl line 4. 04: 1 ... etc ... corion@samson:~ > perl -e "print "0x30"+0;" 48corion@samson:~ >
    I'm not sure what the issue with the test from the command line is, because here I use wrong double quotes which could be messed with by the shell (bash). I can confirm the other results with ActivePerl 5.005 build 517 (yes, I'm running that ancient version here), and the weird quotes trick also works under cmd.exe and NT :
    F:\>perl -e "print "0x30"+0;" 48
    Whatever this means, but maybe some perl luminary can enlighten us.

    Update :Under Win32, ActivePerl build 517, the script works as expected, printing 0 for each number.

Re: Why are hex numbers inside strings extrapolating to numbers (incorrectly)?
by mr.nick (Chaplain) on Feb 26, 2001 at 20:55 UTC
    That is a really good question. I did some experimenting and found it was the "0x<number>" construct that is causing it (the leading 0x is required). However, various experiments haven't revealed a pattern that I have noticed:
    print "0x1" + 0 = 1 print "0x2" + 0 = 1 print "0x3" + 0 = 1.5 print "0x4" + 0 = 1 print "0x5" + 0 = 1.25 print "0x6" + 0 = 1.5 print "0x7" + 0 = 1.75 print "0x8" + 0 = 1 print "0x9" + 0 = 1.125 print "0x10" + 0 = 1
    And first glance, it would seem some sort of floating point conversion is going on, but exactly what, I don't know except that 9/8 = 1.125 (but why eight?) Actually, the following pattern exists:
    print "0x1" + 0 = 1 1/1 = 1 print "0x2" + 0 = 1 2/1 = 2 print "0x3" + 0 = 1.5 3/1.5 = 4 print "0x4" + 0 = 1 4/1 = 4 print "0x5" + 0 = 1.25 5/1.25 = 4 print "0x6" + 0 = 1.5 6/1.5 = 4 print "0x7" + 0 = 1.75 7/1.75 = 4 print "0x8" + 0 = 1 8/1 = 8 print "0x9" + 0 = 1.125 9/1.125 = 8 print "0x10" + 0 = 1 10/1 = 10
    0x01 is probably being interpreted as just a "0x1", whatever that is. Since all the results are on powers of 2 boundaries, I would presume some bit-oriented operation is happening.

    Good question!

      0x10 is really 16.
        No, I think in THIS sitation (which ISN'T taking 0x## as hex numbers) 0x10 is really the same as 0x1, 0x100, 0x183872.

        Tye believes its a problem with the stdlib call atof() and I tend to agree (the same version of Perl produce different results on different OS's).


        addendum: it definately is the atof() function call that is the issue.

        From my Linux box with glibc 2.1.3 (that caused the strange float point results with Perl):

        nicholas@neko/3:(pts-0.neko) ~/tmp > cat test.c #include <stdlib.h> int main(void) { printf("%f\n",atof("0x9")); } nicholas@neko/3:(pts-0.neko) ~/tmp > cc test.c -o test ; ./test 1.125000
        and from my Solaris 2.6 box (which produced "0" with Perl):
        nicholas@peacock2/5 ~ > cat >test.c #include <stdlib.h> int main(void) { printf("%f\n",atof("0x9")); } nicholas@peacock2/5 ~ > cc test.c -o test; ./test 0.000000
Re: Why are hex numbers inside strings extrapolating to numbers (incorrectly)?
by dze27 (Pilgrim) on Feb 26, 2001 at 20:45 UTC
    I've no idea, but running this on my setup does return 0. (winnt, perl 5.6.0, activestate build 623).

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://60834]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others meditating upon the Monastery: (1)
As of 2021-12-06 05:41 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    R or B?



    Results (31 votes). Check out past polls.

    Notices?