Tech Journal Back to Tech Journal

Discussion of Perl integer division gotchas

Here's a program that when run will explain what works in which way:

use integer;
use POSIX;

sub dec2bin {
   my $str = unpack("B32", pack("N", shift));
   #$str =~ s/^0+(?=\d)//;   # otherwise you'll get leading zeros
   return $str;
}

my ($a, $b) = (-3686, 0);

print "This is a demonstration of how rounding in integer math in\n".
     "Perl is different than what you want sometimes. In this case,\n".
     "I will demonstrate how dividing by 4 is different than\n".
     "right-shifting by 2. Also, 'use integer' has been set.\n\n".
     "Pay close attention to the last 3 bits\n\n";

print "A   =$a\n";
print "A   =" . dec2bin($a) . "\n";
print "A>>2=" . ($a >> 4) . "\n";
print "A>>2=" . dec2bin($a >> 4) . "\n";
print "A/4 =" . ($a / 4) . "\n";
print "A/4 =" . dec2bin($a / 4) . "\n";

print "\nThey should've been the same in true integral math, but we have\n".
     "rounding going on!\n";

{
   no integer;
   print "(We'll set 'no integer' temporarily)\n\n";
   print "A/4 =" . ($a / 4) . "\n";
   print "A/4 =" . dec2bin($a / 4) . "\n";
}
{
   no integer;
   print "\n(This time, we'll set 'no integer' and use POSIX::floor()\n\n";
   print "A/4 =" . POSIX::floor($a / 4) . "\n";
   print "A/4 =" . dec2bin(POSIX::floor($a / 4)) . "\n";
   print "\nFinally! They are the same results.\n";
}

    
Last updated on 2005-07-21 14:00:00 -0700, by Shalom Craimer

Back to Tech Journal