Hello Monks,
I have managed to convert positive and negative decimal numbers to binary and vice versa.
Final Update (floating points (+/-) to binary and vice versa for 32 bit and 64 bit accuracy), the code is at the end in case of future reference.Sample of code:
#!/usr/bin/perl use strict; use warnings; use Data::Dumper; sub dec2bin { my $bits = shift; my $str = unpack("B8", pack("c", $bits)); return $str; } sub bin2dec { return unpack("c", pack("B8", substr("0" x 8 . shift , -8))); } my @array = (127,-127); foreach $_ (@array){ if ($_ < 0) { print "Value: $_ is negative\n"; my $negative_b = dec2bin($_); print "Negative binary: ".$negative_b."\n"; my $negative_d = bin2dec($negative_b); print "Negative_binary back to decimal: ".$negative_d."\n"; } else { print "Value: $_ is possitive\n"; my $possitive_b = dec2bin($_); print "Possitive binary: ".$possitive_b."\n"; my $possitive_d = bin2dec($possitive_b); print "Possitive_binary back to decimal: ".$possitive_d."\n"; } } __END__ Value: 127 is possitive Possitive binary: 01111111 Possitive_binary back to decimal: 127 Value: -127 is negative Negative binary: 10000001 Negative_binary back to decimal: -127
I am trying to figure out how to convert positive and negative floating points. For example if I had a number -0.000008 how could I convert the number in binary and back to floating.
I have read on the pack documentation that: F A Perl internal floating-point value (NV) in native format
When I am modifying on my code the "c" to "F" I get the following error:
#!/usr/bin/perl use strict; use warnings; use Data::Dumper; sub dec2bin { my $bits = shift; my $str = unpack("B8", pack("F", $bits)); return $str; } sub bin2dec { return unpack("F", pack("B8", substr("0" x 8 . shift , -8))); } my @array = (0.000008,-0.000008); foreach $_ (@array){ if ($_ < 0) { print "Value: $_ is negative\n"; my $negative_b = dec2bin($_); print "Negative binary: ".$negative_b."\n"; my $negative_d = bin2dec($negative_b); print "Negative_binary back to decimal: ".$negative_d."\n"; } else { print "Value: $_ is possitive\n"; my $possitive_b = dec2bin($_); print "Possitive binary: ".$possitive_b."\n"; my $possitive_d = bin2dec($possitive_b); print "Possitive_binary back to decimal: ".$possitive_d."\n"; } } __END__ Value: 8e-06 is possitive Possitive binary: 10001101 Use of uninitialized value $possitive_d in concatenation (.) or string + at negative2bin&bin2negative.pl line 31. Possitive_binary back to decimal: Value: -8e-06 is negative Negative binary: 10001101 Use of uninitialized value $negative_d in concatenation (.) or string +at negative2bin&bin2negative.pl line 24. Negative_binary back to decimal:
So I assume I am going terribly wrong some where. What I am missing?
Final Update:Thanks to everyone's replies I manage to get this fixed, and understand that floating point 8 bits value is extremely small and not even worth existing.
In IEEE 754-2008 the 16-bit base 2 format is officially referred to as binary16. It is intended for storage (of many floating-point values where higher precision need not be stored), not for performing arithmetic computations. Half-precision floating-point formatSo in conclusion I decided to use 32 bit floating points for positive and negative values.
Sample of code provided bellow:
#!/usr/bin/perl use strict; use warnings; my @array = (3.987654321,-3.987654321); foreach $_ (@array){ if ($_ < 0) { print "Value: $_ is negative\n"; my $negative_b = dec2bin($_,32,"f"); print "Negative binary: ".$negative_b."\n"; my $negative_d = bin2dec($negative_b,32,"f"); print "Negative_binary back to decimal: ".$negative_d."\n"; } else { print "Value: $_ is possitive\n"; my $possitive_b = dec2bin($_,32,"f"); print "Possitive binary: ".$possitive_b."\n"; my $possitive_d = bin2dec($possitive_b,32,"f"); print "Possitive_binary back to decimal: ".$possitive_d."\n"; } } sub dec2bin { my $bits = shift; my $size = shift; my $template = shift; my $str = unpack("B$size", pack($template, $bits)); print "Substring: ".$str."\n"; return $str; } sub bin2dec { my $bits = shift; my $size = shift; my $template = shift; return unpack($template, pack("B$size", substr("0" x $size . $bits + , -$size))); } __END__ Value: 3.987654321 is possitive Substring: 10111010001101010111111101000000 Possitive binary: 10111010001101010111111101000000 Possitive_binary back to decimal: 3.98765420913696 Value: -3.987654321 is negative Substring: 10111010001101010111111111000000 Negative binary: 10111010001101010111111111000000 Negative_binary back to decimal: -3.98765420913696
In case the user wants to round up the values he can use functions like sprintf() or printf() etc.
For example: printf("%.8f", $possitive_d); # prints 3.98765421 or my $rounded = sprintf("%.8f", $negative_d); # prints: -3.98765421 etc.
For floating points 64 bits change the template from f to F and size from 32 to 64 an.Sample of working code provided under:
#!/usr/bin/perl use strict; use warnings; my @array = (3.987654321,-3.987654321); foreach $_ (@array){ if ($_ < 0) { print "Value: $_ is negative\n"; my $negative_b = dec2bin($_,64,"F"); print "Negative binary: ".$negative_b."\n"; my $negative_d = bin2dec($negative_b,64,"F"); print "Negative_binary back to decimal: ".$negative_d."\n"; } else { print "Value: $_ is possitive\n"; my $possitive_b = dec2bin($_,64,"F"); print "Possitive binary: ".$possitive_b."\n"; my $possitive_d = bin2dec($possitive_b,64,"F"); print "Possitive_binary back to decimal: ".$possitive_d."\n"; } } sub dec2bin { my $bits = shift; my $size = shift; my $template = shift; my $str = unpack("B$size", pack($template, $bits)); print "Substring: ".$str."\n"; return $str; } sub bin2dec { my $bits = shift; my $size = shift; my $template = shift; return unpack($template, pack("B$size", substr("0" x $size . $bits + , -$size))); } __END__ Value: 3.987654321 is possitive Substring: 10101110100101010000001101001111101101111110011000001111010 +00000 Possitive binary: 1010111010010101000000110100111110110111111001100000 +111101000000 Possitive_binary back to decimal: 3.987654321 Value: -3.987654321 is negative Substring: 10101110100101010000001101001111101101111110011000001111110 +00000 Negative binary: 10101110100101010000001101001111101101111110011000001 +11111000000 Negative_binary back to decimal: -3.987654321
Thanks again for everyone's assistance to help me understand the process and provided me so much material to read on.
In reply to How to convert negative and positive floating points to binary and vice versa by thanos1983
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |