Math::BigInt with INN

Julien ÉLIE julien at trigofacile.com
Sun Jun 28 15:39:42 UTC 2009


Hi,

We currently use "bigint.pl" in two scripts for CNFS.

package bigint;
#
# This library is no longer being maintained, and is included for backward
# compatibility with Perl 4 programs which may require it.

And we cannot use Perl warnings with them because of:

% perl -w -e 'require "bigint.pl"; print bmul(1, 1);'
Use of uninitialized value in addition (+) at /usr/share/perl/5.10/bigint.pl line 220.
+1


Could we use Math::BigInt instead?


It would for instance give for cnfsheadconf:


--- cnfsheadconf.in     2009-06-28 16:51:24.000000000 +0200
+++ cnfsheadconf.in       2009-06-28 17:17:51.000000000 +0200
@@ -20,8 +20,8 @@
 use vars qw($opt_h $opt_w);
 use Getopt::Long;

-# required for >32bit ints
-require 'bigint.pl';
+# Required for >32bit integers.
+use Math::BigInt;

 my($conffile) = "$INN::Config::pathetc/cycbuff.conf";
 my($storageconf) = "$INN::Config::pathetc/storage.conf";
@@ -29,51 +29,41 @@
 sub bhex {
     my $hexValue = shift;
     $hexValue =~ s/^0x//;

-    my $integerValue = '0';
+    my $integerValue = Math::BigInt->new('0');
     for (my $i = 0; $i < length($hexValue); $i+=2) {
         # Could be more efficient going at larger increments, but byte
-        # by byte is safer for the case of 9 byte values, 11 bytes, etc..
+        # by byte is safer for the case of 9 byte values, 11 bytes, etc.

         my $byte = substr($hexValue,$i,2);
         my $byteIntValue = hex($byte);

-        $integerValue = bmul($integerValue,'256');
-        $integerValue = badd($integerValue,"$byteIntValue");
-        }
-
-    $integerValue =~ s/^\+//;
-    return $integerValue;
+        # bmuladd() is only in Perl >= 5.10.0.
+        $integerValue->bmul('256');
+        $integerValue->badd("$byteIntValue");
     }

+    my $result = $integerValue->bstr();
+    $result =~ s/^\+//;
+    return $result;
+}
+
 sub bint2hex {
     my $d = shift;
     my $o = 0;

-    while ($d > 0) {
-        my $h = bmod("$d",'16');
-        $d = bdiv("$d",'16');
+    my $integerValue = Math::BigInt->new("$d");
+    while ($integerValue->is_pos() and not $integerValue->is_zero()) {
+        my $h = $integerValue->copy()->bmod('16')->bstr();
+        $integerValue->bdiv('16');
         $h =~ s/^\+//;
         $h='a' if $h eq '10';
         $h='b' if $h eq '11';





Note that I see afterwards:

    my($len) = bhex($lena);
    my($free) = bhex($freea);
    print " Buffer $name, len: ";
    printf("%.2f", $len / (1024 * 1024));
    print " Mbytes, used: ";
    printf("%.2f Mbytes", $free / (1024 * 1024));

There was no bdiv() here to compute it.  No need to?  (string division)
It properly gives a right answer, though:

% ./cnfsheadconf -c FR1
 Buffer FR1, len: 1536.00 Mbytes, used: 1295.12 Mbytes (84.3%)   1 cycles
 Meta FR, order: 1, current: TRUE, blocksize: 512
 Newest: 2009-06-28 16:51:11,    0 days,  0:00:24 ago

-- 
Julien ÉLIE

« XXII ! Voilà les Romains ! » (Astérix) 




More information about the inn-workers mailing list