thanos1983 has asked for the wisdom of the Perl Monks concerning the following question:
Hello Monks,
More I get closer to my solution more problems I discover. I am trying to convert decimals into 16 bits.
I am using pack and unpack, which works perfect when the first digit of the decimal number is not zero:
I know it does not make sense to have a decimal starting with zero. The reason is that I have a number such as 0.02911 where I am splitting the string before the dot and after so I can send them separately.
So my alternative option would be to convert the decimal to binary B16 send in and then reverse the process. Cookbook 2.4. Converting Between Binary and Decimal
Sample of code with both proposed solutions:
#!/usr/bin/perl use warnings; use strict; my $sampleDecimal = "02911"; my $uint16 = pack 'n', $sampleDecimal; my $decimal = unpack 'n', $uint16; print "Decimal: " . $decimal . "\n"; my $binaryStr = desimalToBinary( $sampleDecimal , 16 , 'n' ); print "Binary: " . $binaryStr . "\n"; my $decimalStr = binaryToDecimal( $binaryStr , 16 , 'n' ); print "Decimal from binary: " . $decimalStr . "\n"; sub binaryToDecimal { my $binary = shift; my $bitSize = shift; my $template = shift; return unpack($template, pack("B$bitSize", substr("0" x $bitSize . + $binary, -$bitSize))); } sub desimalToBinary { my $decimal = shift; my $bitSize = shift; my $template = shift; my $bitStr = unpack("B$bitSize", pack($template, $decimal)); $bitStr =~ s/^0+(?=\d)//; # otherwise you'll get leading zeros return $bitStr; } __END__ Decimal: 2911 Binary: 101101011111 Decimal from binary: 2911
Unfortunately, both proposed solutions do give the same result. A non leading zero decimal. I know I could add manually the leading zero, but in cases the number produced with a non zero digit, then I will have completely wrong number.
So the question, is it possible to get the leading zero through pack and unpack using 'n' as a template?
Update 2: Well it seems that the best solution is to use, sprintf as roboticus proposed.
Sample of code/solution:
#!/usr/bin/perl use warnings; use strict; my $sampleDecimal = "02911"; my $uint16 = pack 'n', $sampleDecimal; my $decimal = unpack 'n', $uint16; $decimal = sprintf("%05d", $decimal); print "Decimal: " . $decimal . "\n"; my $binaryStr = desimalToBinary( $sampleDecimal , 16 , 'n' ); print "Binary: " . $binaryStr . "\n"; my $decimalStr = binaryToDecimal( $binaryStr , 16 , 'n' ); $decimalStr = sprintf("%05d", $decimalStr); print "Decimal from binary: " . $decimalStr . "\n"; sub binaryToDecimal { my $binary = shift; my $bitSize = shift; my $template = shift; return unpack($template, pack("B$bitSize", substr("0" x $bitSize . + $binary, -$bitSize))); } sub desimalToBinary { my $decimal = shift; my $bitSize = shift; my $template = shift; my $bitStr = unpack("B$bitSize", pack($template, $decimal)); $bitStr =~ s/^0+(?=\d)//; # otherwise you'll get leading zeros return $bitStr; } __END__ Decimal: 02911 Binary: 101101011111 Decimal from binary: 02911
Thank you for your time and effort.
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: How to pack and unpack 16 bit decimal with leading zero
by roboticus (Chancellor) on Jul 27, 2015 at 03:20 UTC | |
by thanos1983 (Parson) on Jul 27, 2015 at 10:36 UTC | |
|
Re: How to pack and unpack 16 bit decimal with leading zero (no)
by tye (Sage) on Jul 27, 2015 at 03:16 UTC | |
by thanos1983 (Parson) on Jul 27, 2015 at 10:31 UTC | |
|
Re: How to pack and unpack 16 bit decimal with leading zero
by BrowserUk (Patriarch) on Jul 27, 2015 at 07:57 UTC | |
by thanos1983 (Parson) on Jul 27, 2015 at 10:42 UTC | |
by BrowserUk (Patriarch) on Jul 27, 2015 at 10:47 UTC | |
|
Re: How to pack and unpack 16 bit decimal with leading zero
by RichardK (Parson) on Jul 27, 2015 at 10:56 UTC |