Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris

Hex Question(s)

by deadlock (Initiate)
on Mar 27, 2008 at 16:09 UTC ( #676772=perlquestion: print w/replies, xml ) Need Help??

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

Hello monks, I have a question that someone might be able to help me with. I need to take an integer and convert it to hex. As an example, if I take 1501299200 as my integer:
$theInt = 1501299200; $theHex = sprintf("%lx", $theInt); # returns 597c0200;
Now, this much is fine - but how do I convince Perl that $theHex is a hex value and not a simple string?
Any help would be much appreciated.

Replies are listed 'Best First'.
Re: Hex Question(s)
by kyle (Abbot) on Mar 27, 2008 at 17:03 UTC

    I think you could do what you want if you create $theHex as an object and use overload. A quick example:

    package Number::HexString; use overload '""' => sub { sprintf '0x%x', ${$_[0]} }, '0+' => sub { ${$_[0]} }, 'fallback' => 1; sub new { my $class = shift; my $number = 0+shift; return bless \$number, $class; } package main; my $theHex = Number::HexString->new( 1501299200 ); print "$theHex plus 1 is ", $theHex + 1, "\n"; print 'The number ', $theHex+0, " is '$theHex'\n"; __END__ 0x597c0200 plus 1 is 1501299201 The number 1501299200 is '0x597c0200'

    This really seems like overkill, however, and you may have to fiddle with it a while before it does what you really want.

Re: Hex Question(s)
by Corion (Pope) on Mar 27, 2008 at 16:15 UTC

    What is the difference between a "hex value" and a "simple string"?

      That's the question I guess - is there any? Doesn't a hex value normally begin with 0x? And it isn't it normally specified without quotes?
      $hex = 0x1234; #prints 4660
      as opposed to
      $hex = '0x1234'; #prints 0x1234

        What I was aiming at is, that Perl makes no distinction between the base of numbers. You may specify a number in hexadecimal notation, that is, starting with 0x, or as a plain integer, that is, in decimal notation, or in octal notation, starting with a leading zero. Internally, Perl will treat all these as numbers, because they get converted to the Perl-internal representation for numbers.

        If you have a string and you want to perform arithmetic operations on it, the easiest way to do that is if the string looks_like_number, that is, is in decimal notation (at least for this discussion). Otherwise, you have to convert from the notation you have to the decimal notation. For example, the functions hex and oct do that.

        But maybe, we can just leave the plane of metaphysical discussions of the representation of numbers, and the numbers themselves (and whether numbers exist without representation) and you tell us what problem you're trying to solve?

Re: Hex Question(s)
by pc88mxer (Vicar) on Mar 27, 2008 at 16:20 UTC
    Is the hex() function what you are looking for?
    my $theHex = "100"; print hex($theHex), "\n"; # prints: 256

      No, that's converting a hex value to an integer. That's not what I'm trying to do - I'm actually doing the opposite: I'm converting an integer to hex but Perl doesn't appear to be treating the resulting string as hex.

      Put it this way.

      print 0x1234+0x4321; # returns 21605 print '0x1234'+'0x1234'; returns 0 because you can't concatenate strin +gs in this way

        No, Perl's treating it like any other hex string in that it's not a valid number. Perl understands hex numeric literals, but they're silently converted to decimal under the hood. If you want to do manipulation of numbers then you need to use hex to parse the number to decimal and then only reformat as hex on the way out after you're done manipulating it.

        Update: Ooh, better said here up above.

        The cake is a lie.
        The cake is a lie.
        The cake is a lie.

        Are you sure that hex isn't what you're looking for?
        perl -le "print hex('1234') + hex('4321')" 21845 perl -le "print hex('0x1234') + hex('0x4321')" 21845
Re: Hex Question(s)
by YuckFoo (Abbot) on Mar 27, 2008 at 16:28 UTC
    Prepend '0x' to the string and it will maintain its numeric value.
    #!/usr/bin/perl use strict; no warnings 'numeric'; my $this = sprintf("0x%x", 40); my $that = sprintf("0x%x", 2); my $other = $this + $that; printf "$other %x\n", $other; __END__ 42 2a
    Update: Added no warnings for the -w happy...

    Update: This is perl, v5.6.0 built for i386-linux

      I guess you didn't try your program:

      C:\>perl -w Argument "0x2" isn't numeric in addition (+) at line 8. Argument "0x28" isn't numeric in addition (+) at line 8. 0 0

      This oneliner shows that this isn't the case:

      >perl -le "print '0x42' + '0x10'" 0

      But of course, if you leave off the single quotes, Perl will interpret the numbers as numbers (in hexadecimal notation) and add them like it does add all numbers (regardless of their notation):

      >perl -le "print 0x42 + 0x10" 82

      ... but that's because internally, Perl does just see the numbers as numbers (without any representation to any base).

      What version of Perl are you using? When I run your code on my system (WinXP, ActivePerl 5.8.8), I get an incorrect answer. I added a the use warnings pragma to your code and got this result:

      C:\> Argument "0x2" isn't numeric in addition (+) at C:\ line 9. Argument "0x28" isn't numeric in addition (+) at C:\ line 9. 0 0

      You can specify hexadecimals in literal code by appending an '0x' to the value. I suppose, if you really wanted to get to a hexadecimal from a string, you could use string eval.

      my $this = sprintf("0x%x", 40); my $that = sprintf("0x%x", 2); my $other = eval "$this + $that"; printf "$other %x\n", $other;

      I'd be inclined to go with hex, though.

      TGI says moo

      perl -w Argument "0x2" isn't numeric in addition (+) at line 7. Argument "0x28" isn't numeric in addition (+) at line 7. 0 0
Re: Hex Question(s)
by nikosv (Chaplain) on Mar 28, 2008 at 06:55 UTC
    the oct function converts a string into a number. prepend 0x to your string an pass it through the oct function
    print 0x1234+0x4321;#prints 21845 print '0x1234'+'0x4321';#prints 0 print oct('0x1234')+oct('0x4321); #prints 21845 or $a='0x1234'; $b='0x4321'; print oct($a)+oct($b);

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://676772]
Approved by Corion
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others scrutinizing the Monastery: (6)
As of 2021-04-14 10:38 GMT
Find Nodes?
    Voting Booth?

    No recent polls found