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 format

So 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.

Seeking for Perl wisdom...on the process of learning...not there...yet!

In reply to How to convert negative and positive floating points to binary and vice versa by thanos1983

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.