Tweet


#include(./perl の bignum)
* perl の bignum [#e9304035]
最近,時刻やストレージの容量など,32 bit over の整数を扱わざるをえない機会が多くなってきている.
もちろん,( 32 bit CPU 上での ) 素の perl でも 2**32 を越える整数を扱うことはできるが,内部的には浮動小数点で保持しているはずであり,何かの機会にひょっこり誤差が出てきそうで気味が悪い.

こういうときに多桁整数演算用のパッケージ Math::BitInt がある.
が,これは純粋に perl クラスで実装されており,単純に足し算するだけでも

 #!/usr/bin/perl
 use Math::BigInt;
 
 $a = Math::BigInt->new ( '1' ); # $a = 1;
 $b = Math::BigInt->new ( '2' ); # $b = 2;
 
 $a->badd( $b );                 # $a += $b;
 printf "%s\n", $a->bstr();

のような表記になり,ちょっと使いづらい.

あと,bignum というクラス(?)もある.

 #!/usr/bin/perl
 use bignum;
 printf "%s\n", 1+2;

内部的には Math::BigInt と Math::BigFloat を使用しているそうであるが,これらとの大きな違いは
- 数値定数を全て Math::BigInt or Math::BigFloat のインスタンスとして扱う
- 演算子もオーバロードされる

というわけで,プログラムの先頭に use bignum; と宣言するだけで,今までのプログラムが多桁演算対応に早変わりしてくれる.
もちろん,演算速度は犠牲になるが,それは多桁演算とのトレードオフというものである.

が,この bignum,妙な癖があるようで

 #!/usr/bin/perl
 package Foo;
 use bignum;
 
 sub new {
   my $class = shift;
   my $self = {};
   my %param = @_;
   
   $self->{name} = $param{name}; 
   
   bless $self, $class;
 }
 
 
 sub set {
   my $self = shift;
   my %kv = @_;
   
   while ( my ( $k, $v ) = each %kv ) {
     $self->{hash}->{$k} = $v;
   }
  1;
 }
 
 
 sub show {
   my $self = shift;
   my $kv = $self->{hash};
   
   printf "--- %s ---\n",  $self->{name};
   
   my %kloop = %$kv;
   while ( my ( $k, $v ) = each %kloop ) {
     $v = 'UNDEF' if !defined $v;
     print "$k => $v\n";
   }
   1;
 }
 
 
 sub DESTROY {
   my $self = shift;
   
   show ( $self );
   1;
 }
 1;
 #---
 $foo = Foo->new( name => 'explicit' );
 $foo->set ( 1 => 2, 3 => 4, 5 => 6 );
 $foo->show();
 undef $foo;
 
 $foo = Foo->new( name => 'implicit' );
 $foo->set ( 1 => 2, 3 => 4, 5 => 6 );
 $foo->show();
 exit;

このプログラムを実行してみると…
 --- explicit ---
 1 => 2
 3 => 4
 5 => 6
 --- explicit ---
 1 => 2
 3 => 4
 5 => 6
 --- implicit ---
 1 => 2
 3 => 4
 5 => 6
 --- implicit ---
 1 => UNDEF
 3 => 4
 5 => 6
exit より後では,インスタンスが一部消滅してしまうらしい.

use bignum; の行をコメントアウトして実行すると,もちろん
 --- explicit ---
 1 => 2
 3 => 4
 5 => 6
 --- explicit ---
 1 => 2
 3 => 4
 5 => 6
 --- implicit ---
 1 => 2
 3 => 4
 5 => 6
 --- implicit ---
 1 => 2
 3 => 4
 5 => 6
期待した通りの結果が得られる.

うーん.


トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS