Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

I need Hex conversion, not!

by Anonymous Monk
on Jan 07, 2013 at 13:01 UTC ( #1012021=perlquestion: print w/ replies, xml ) Need Help??
Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hello,

I need to use hex numbers for something but when I assign hex number to something, it prints out as decimal. I do not want that and I do not want to waste my code as re-convertion

$SM = 0xFE; print $SM, "\n" ; #it prints out 254 #but of course if I write it like this; printf("0x%02X",$SM); #it prints out 0xFE

I want to use many variables like $SM, so I dont want to write "0x%02X", etc. everywhere. I need direct output in hex, or even better, only hex part like, FE, so what should I do ?

Comment on I need Hex conversion, not!
Download Code
Re: I need Hex conversion, not!
by Corion (Pope) on Jan 07, 2013 at 13:04 UTC

    Numbers are numbers. Their format is determined on output. See sprintf.

    If you want to use strings, then use strings.

    $SM = "0xFE"; print $SM;

    Of course, for strings, there is no numeric addition. Maybe you want to tell us more about your use case.

Re: I need Hex conversion, not!
by LanX (Canon) on Jan 07, 2013 at 13:06 UTC
    > so what should I do ?

    keep the hexnumbers as strings ...

    DB<121> $SM = 0xFE; => 254 DB<122> $SM = "0xFE"; => "0xFE" DB<123> print $SM => 1 0xFE

    ...or write a subroutine printhex() which automatically fulfills your wishes by converting any numeric scalar to a hexstring before printing.

    Cheers Rolf

Re: I need Hex conversion, not!
by blue_cowdawg (Monsignor) on Jan 07, 2013 at 13:09 UTC
        I need to use hex numbers for something but when I assign hex number to something

    Your point is...?

    If you want to print as hex you need to use the format string as you show in your second example...

    printf("0x%02X",$SM);

    If you don't want to do that "everywhere" you can always create a sub such that:

    | hand waving here... my $n = 0x85; printf "and the majic number is: %s\n",as_hex($n); | more handwaving exit(0); sub as_hex{ my $x=shift; sprintf "%X",$x; }


    Peter L. Berghold -- Unix Professional
    Peter -at- Berghold -dot- Net; AOL IM redcowdawg Yahoo IM: blue_cowdawg
Re: I need Hex conversion, not!
by choroba (Abbot) on Jan 07, 2013 at 13:31 UTC
    You can profit from the core Scalar::Util's dualvar:
    #!/usr/bin/perl use warnings; use strict; { package DecHex; use Scalar::Util qw(dualvar); sub create { my $num = shift; my $string = sprintf '%X', $num; my $self = dualvar($num, $string); } } my $x = DecHex::create 0xFE; print "$x, ", 0+$x, "\n";
    لսႽ ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ

      That is really nice, I think this is what I wanted, thank you.

Re: I need Hex conversion, not!
by Anonymous Monk on Jan 07, 2013 at 13:44 UTC

    Thanks for the replies, but how is it useful that using a number as string? Because I'm not sure about the results yet. The thing is, I'm trying to learn a new protocol that I should use it to give orders to a machine remotely. Also I need to calculate a variable so I need numeric values instead of strings.

    #!/usr/bin/perl use warnings; use strict; use IO::Socket; my ($SM,@ADRDSTN,@ADRSRC,$MID,$MDLH,$MDLL,$SUBMID,@CHreq,@Pity,@Flags, +@Timeout,@Level,$NumOfSrcEl,@SrcEl,$NumOfDstnEl,@DstnEl,$Rsvd,@messag +e,$CHECKSUM,$EM); $SM = 0xfe; @ADRDSTN= (0x00, 0x09, 0x01, 0x00); @ADRSRC= (0x00, 0x08, 0x01, 0x00); $MID= 0x01; $MDLH= 0x00; $MDLL= 0x18; $SUBMID= 0x00; @CHreq= (0x00, 0x61); @Pity= (0xFF, 0x05); @Flags= (0x00, 0x20); @Timeout= (0x00, 0x00); @Level= (0x00, 0x00); $NumOfSrcEl= 0x01; @SrcEl= (0x00, 0xFF, 0x00, 0x84, 0x10, 0x00); $NumOfDstnEl= 0x01; @DstnEl= (0x08, 0x10, 0x00, 0x01, 0x01); $Rsvd= 0x00; @message= (@ADRDSTN,@ADRSRC,$MID,$MDLH,$MDLL,$SUBMID,@CHreq,@Pity,@Fla +gs,@Timeout,@Level,$NumOfSrcEl,@SrcEl,$NumOfDstnEl,@DstnEl,$Rsvd); $EM= 0xFD; my $count=0; $count += $message[$_] for 0..@message-1 ; $count = 256 - ($count % 256); $CHECKSUM=$count; my @VPAP=($SM,@message,$CHECKSUM,$EM); my $sock = new IO::Socket::INET ( PeerAddr => 'localhost', PeerPort => '7070', Proto => 'tcp', ); die "Could not create socket: $!\n" unless $sock; print $sock @VPAP; close($sock);

      Try this, and when it works, think about why it works:

      #!/usr/bin/perl use warnings; use strict; use IO::Socket; my $SM = "\xfe"; my $ADRDSTN= "\x00\x09\x01\x00"; my $ADRSRC= "\x00\x08\x01\x00"; my $MID= "\x01"; my $MDLH= "\x00"; my $MDLL= "\x18"; my $SUBMID= "\x00"; my $CHreq= "\x00\x61"; my $Pity= "\xFF\x05"; my $Flags= "\x00\x20"; my $Timeout= "\x00\x00"); my $Level= "\x00\x00"; my $NumOfSrcEl= "\x01"; my $SrcEl= "\x00\xFF\x00\x84\x10\x00"; my $NumOfDstnEl= "\x01"; my $DstnEl= "\x08\x10\x00\x01\x01"; my $Rsvd= "\x00"; my $message= $ADRDSTN . $ADRSRC . $MID .$MDLH . $MDLL . $SUBMID . $CHreq . $Pity .$Flags . $Timeout . $Level . $NumOfSrcEl . $SrcEl . $NumOfDstnEl . $DstnEl . $Rsvd; my $EM= "\xFD"; my $count=0; $count += $message[$_] for 0..@message-1 ; $count = 256 - ($count % 256); $CHECKSUM= chr( $count ); my $VPAP= $SM . $message . $CHECKSUM . $EM; my $sock = new IO::Socket::INET( PeerAddr => 'localhost', PeerPort => '7070', Proto => 'tcp', ) or die "Could not create socket: $!\n"; print $sock $@VPAP; close($sock);

      With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.

        Thanks for the help but when I run the code, it cannot calculate addition of members of @message

        Argument "\0^I^A\0\0^H^A\0^A\0^X\0\0aM-^?^E\0 \0\0\0\0^A\0M-^?\0M-^D.. +." isn't numeric in addition (+) at VPAP_test.pl line 32. Wide character in print at VPAP_test.pl line 37. þ1ý

        To be able to run it, I fixed some errors

        #!/usr/bin/perl use warnings; use strict; use IO::Socket; my $SM = "\xfe"; my $ADRDSTN= "\x00\x09\x01\x00"; my $ADRSRC= "\x00\x08\x01\x00"; my $MID= "\x01"; my $MDLH= "\x00"; my $MDLL= "\x18"; my $SUBMID= "\x00"; my $CHreq= "\x00\x61"; my $Pity= "\xFF\x05"; my $Flags= "\x00\x20"; my $Timeout= "\x00\x00"; my $Level= "\x00\x00"; my $NumOfSrcEl= "\x01"; my $SrcEl= "\x00\xFF\x00\x84\x10\x00"; my $NumOfDstnEl= "\x01"; my $DstnEl= "\x08\x10\x00\x01\x01"; my $Rsvd= "\x00"; my @message= $ADRDSTN . $ADRSRC . $MID .$MDLH . $MDLL . $SUBMID . $CHreq . $Pity .$Flags . $Timeout . $Level . $NumOfSrcEl . $SrcEl . $NumOfDstnEl . $DstnEl . $Rsvd; my $EM= "\xfd"; my $count=0; $count += $message[$_] for 0..@message-1 ; $count = 256 - ($count % 256); my $CHECKSUM= chr( $count ); my @VPAP= $SM . @message . $CHECKSUM . $EM; print @VPAP,"\n";
Re: I need Hex conversion, not!
by tobyink (Abbot) on Jan 07, 2013 at 16:18 UTC

    This works, but it will give you a slight performance hit. Unless you're doing serious number crunching it'll probably be acceptable...

    use strict; use warnings; sub hexnum { package HexNum; use base 'Math::BigInt'; use overload q[""] => 'as_hex'; __PACKAGE__->new(@_); } my $var = hexnum 0x2F; $var += 3; $var += hexnum 0x02; print "$var\n";
    perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'

      Wow, that is cool. Btw, is there a way to ignore 0x prefix without substr, or anything ?

        use strict; use warnings; sub hexnum { package HexNum; use base 'Math::BigInt'; use overload q[""] => 'as_hex_without_0x'; __PACKAGE__->new(@_); } sub HexNum::as_hex_without_0x { substr($_[0]->as_hex, 2); } my $var = hexnum 0x2F; $var += 3; $var += hexnum 0x02; print "$var\n";
        perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'
Re: I need Hex conversion, not!
by AnomalousMonk (Abbot) on Jan 07, 2013 at 22:54 UTC

    Here's a cut-down example of a pack approach to building a socket message. I leave you to fiddle with the checksum until it comes out right; I can never seem to get this sort of thing first-try.

    >perl -wMstrict -le "my $SM = 0xfe; my @ADRDSTN = (0x00, 0x09, 0x01, 0x00); my $MID = 0x01; my $MDLH = 0x00; my $MDLL = 0x18; my $EM = 0xFD; ;; my @message = (@ADRDSTN, $MID, $MDLH, $MDLL); ;; my $packed_message = pack 'C*', @message; ;; my $checksum = 256 - unpack '%8C*', $packed_message; ;; my $msg_for_socket = pack 'C a* C C', $SM, $packed_message, $checksum +, $EM; ;; my $msg_for_debug = unpack 'H*', $msg_for_socket; print qq{'$msg_for_debug'}; " 'fe00090100010018ddfd'

      Thank you for your message but I'll continue with the methods above for now

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others imbibing at the Monastery: (3)
As of 2014-11-23 03:47 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My preferred Perl binaries come from:














    Results (128 votes), past polls