develooper Front page | perl.perl5.porters | Postings from August 2001

Re: [ID 20010723.001] perl 5.6.1: BigInt booleans cannot handle negatives (please close)

From:
Tels
Date:
August 2, 2001 14:05
Subject:
Re: [ID 20010723.001] perl 5.6.1: BigInt booleans cannot handle negatives (please close)
Message ID:
perl.perl5.porters-41280@nntp.perl.org
-----BEGIN PGP SIGNED MESSAGE-----

Moin,

Bryce, thank you for your bug-report. Version v1.39 of Bigint is out, and
fix your problem (Except that I screwed bxor(-$x,-$y), v1.40 will be out
shortly and fix this _finally_ *sigh* I need more coffee #%-/=

(Note to bug-admin: Please close this bug, or if you are cautios, wait
until I upload v1.40 ;)

Please note that you need a few tricks to convince Perl to do the 'right'
(aka: What You Mean[tm]) thing:

First, you _must_ use integer to get the "correct" (aka platform
independend) values for negative values for & | ^ ~.

$x = -1; $y = -1; print "$x & $y = ",$x & $y,"\n";
use integer;
$x = -1; $y = -1; print "$x & $y = ",$x & $y,"\n";

The first one will print a large positive value (probably depending on
the number of bits of a perl scalar, e.g. 32 or 64), while the second one
prints -1.

Second, you need to make sure that _at least one_ of the numbers is a
number, not a string. Otherwise, a string-bitwise-operation will performed,
and the ASCII (or EBCDsomething) value ofthe number might surprise you:

$x = 1; $y = 3;
print $x ^ $y,"\n";
$x = "1"; $y = 3;
print $x ^ $y,"\n";
$x = 1; $y = "3";
print $x ^ $y,"\n";
$x = "1"; $y = "3";
print $x ^ $y,"\n";

This is independed from use integer;. To make the last line work like you
intended, use +0 like this:

print (0+$x) ^ $y,"\n";

Sorry about this, I don't like it either! 


Thus, a short test program would run like the following. Note that the 0+
is technically not needed, since $x and $y _are_ numbers, but just
there to make sure nothing bad happens when someone changes for( ... ) to
foreach (qw/ -1 0 1/):


#!/usr/bin/perl -w

use integer;
use Math::BigInt;

for ($x = -16; $x < 16; $x++)
  {
  for ($y = -16; $y < 16; $y++)
    {
    $z = Math::BigInt->new($x);
    $u = Math::BigInt->new($y);
    print "differs for $x, $y\n"
    if ((0+$x ^ $y) != ($z ^ $u));
    }
  }


I hope this helps,

Tels

- -- 
perl -MMath::String -e 'print \
Math::String->from_number("215960156869840440586892398248"),"\n"'

 http://bloodgate.com/thief/     Thief - The Dark Project
 http://bloodgate.com/perl       My current Perl projects
 http://freedomforlinks.de       Fight for your right to link.
 PGP key available on http://bloodgate.com/tels.asc or via email 

-----BEGIN PGP SIGNATURE-----
Version: 2.6.3i
Charset: latin1

iQEVAwUBO2mou3cLPEOTuEwVAQEf2Qf+PBAWGGlDuaZ0h/EVnOyl+KcZdsr5shXx
3c50YqaqGvEEtyLtG8oyBMaKDRoHxFIFLZ5o95FWlyWs7fiW0PHD5QZ4m08o+2xs
tbdSkqtYjBMr70dgWSkFUjfmA5AJC0Kk3y9wvz0nj9oD00YPODAnatRsZjy6D0jy
HiTtHfrEemzXDv1bPYrElSIpk+W70scKkoPEmVabsHEVhk7V5ZfzkEwikCeMPPUL
AO+Mwh+m//M0hc2nYcmwxQolW/n3n/4Y1v5ozBTIidwqXDBn2A//Nzwx/DX/fWWc
VKs8o8c/8V2qcA+Z1Xxjl38XiOXvAXYNBNpnYMOE7ZacGOAl/LyXkQ==
=CdFj
-----END PGP SIGNATURE-----



nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About