Location : Home > Languages > Perl > Package
Title : Math::Fleximal
Toolbox Logo

名称

 Math::Fleximal - 整数表現


概要

use Math::Fleximal;
my $number = new Math::Fleximal($value, $flex);

# 値を設定
$number = $number->set_value("- $fleck_4$fleck_3");
$number = $number->set_value($another_number);

# 慣れた形式でオブジェクトを取得
my $string = $number->to_str();
my $integer = $number->base_10();

# 同じ精度でさらに数値をコンストラクト
my $copy = $number->dup();
my $other_number = $number->dup($value);
my $absolute_value = $number->abs();

# 新しい表現
my $in_new_base = $number->change_flex($new_flex);

# 計算 − 異なる精度で。答えは $number に。
$result = $number->add($other_number);
$result = $number->mul($other_number);
$result = $number->subtr($other_numer);
$result = $number->div($other_number);

# 整数に特化した計算
$result = $number->gcd($other_number);
$result = $number->mod($other_number);

my $comparison = $number->cmp($other_number);

説明

 これは異なる基に基づく表現で表された整数同士の計算を行うパッケージである。基 n の算法には n 種の記号が必要である。私はこれをグリフ(glyphs)と呼んでいるが、それらは本当は文字列ではない。マックィーンの風変わりな示唆にしたがって文字列表現の集合を flex、個々の字を flecks と表すことにし、Math::Fleximal という名前にした。ただしこの名前はいささか非公式ではあるが。

 これは文字が何であれ、互いに変換することで基本算法を行うものである。
 Math::BigInt のように大きな整数を扱うこともできる。ただしパフォーマンスはよくないが。(Bit::Vector を利用したほうが Math::BigInt よりもよいパフォーマンスが得られる。) それを使う代わりに数値のサイズの上限を設定しないで Math::BaseCalc を使うことも可能である。以下の例は MD5 ハッシュを使いやすい表現に置き換えるものである。

use Math::Fleximal;
use Digest::MD5 qw(md5_hex);
my $digest = hex2alpha(md5_hex($data));

# 16進数表現を英数字(すなわちbase 62)に変換する
sub hex2alpha {
  Math::Fleximal->new(
    lc(shift), [0..9, 'a'..'f']
  )->change_flex(
    [0..9,'a'..'z','A'..'Z']
  )->to_str();
}

new

 新しい数をコンストラクトする。引数は値、他の引数のハッシュがその後に続く flex を形成する flecks の配列である。flex はデフォルトでは [0..9] で、他の引数はデフォルトでは空である。
 これで10以外の基の計算を行うことができる。基は flex 内の flecks の数である。以下のように記述することで base 16 で記述できる。

my $base_16 = new Math::Fleximal("4d", [0..9, 'a'..'f']);

 値が渡されれば既存の Math::Fleximal または(上記のように)現在の flex でパースされた文字列として扱われる。

 利用可能なキーは以下の通りである。

 strip とマッチするものはパース前に文字列から除去される。長い値における字を識別できるようによくある方法で処理できるようデフォルトは qr/[\s\.,_]/ に設定されている。

 flecks への文字列のパースでは大文字小文字を区別する。あいまいな表現ではパースがうまく処理できないこともある。

dup

 既存の数値をコピーする。このコピーは既存の数値を変換することなしに行われる。dup が値を受けとれば新しいインスタンスが代わりに値を保持する。

set_value

 これは内部値を設定しオブジェクトを返す。
 既存のインスタンス(他の基でもよい)または文字列に新しい値を設定することができる。まず最初の空白は削除し、その後オプションで +- や flecks (少なくとも1つ)が続く。最初の fleck が + または - から始まるか、符号が含まれていないかで混乱が生じるかも知れない。

to_str

 現在の値を現在の flex を用いた表現の文字列を返す。これは常に符号を含み、符号の前には空白はない。

base_10

 内部値を基を10とする表現に変更する。
 返り値は Perl の通常の整数表現よりも大きいものである。

change_flex

 新しい flex をとり、現在のものに変更する。必要であれば明示的に基を変更する。

add

 現在の数値に1つ以上の数値を加えて現在の表現で返す。
 数値はいかなる基においてもオブジェクトまたは現在の表現における文字列であってもよい。

mul

 現在の数値に1つ以上の数値を乗じて現在の表現で返す。
 数値はいかなる基においてもオブジェクトまたは現在の表現における文字列であってもよい。

subtr

 現在の数値から1つ以上の数値を引いて現在の表現で返す。
 数値はいかなる基においてもオブジェクトまたは現在の表現における文字列であってもよい。

div

 現在の数値に1つ以上の数値を渡し、これを割って現在の表現で返す。
 リストコンテキストでは答えを現在の表現における配列で返す。
 剰余は商の絶対値よりも小さい値で、正でなければならない。数値はいかなる基においてもオブジェクトまたは現在の表現における文字列であってもよい。

gcd

 1つまたは2つの整数をとり、最大公約数を計算し、リストにして返す。

mod

 div で割った剰余を返す。スカラコンテキストでは剰余だけを返す。以下の例では1000を10で割った剰余を返す。

my $digit = $number->mod(1000, 10);

cmp

 2つの値をとり、前者が後者よりも小さければ -1 を、等しければ 0 を、大きければ 1 を返す。(文字列に対する cmp のようなもの)

one

 現在の flex 内の 1 を返す。

zero

 現在の flex 内の 0 を返す。


バグ

 30,000 より大きなサイズでは落ちるかも知れない。
 文字列を数値に変換する際のわずかなあいまいさを解決するための努力が必要である。


著者とライセンス

 Copyright 2000-2001, Ben Tilly (<btilly@gmail.com>)

 Math::Fleximal は Perl 本体と同等の条件で複製及び再配布してもよい。

Toolbox Logo
Updated : 2007/04/09