Location : Home > Languages > Perl > Package
Title : Math::Units::PhysicalValue
Toolbox Logo

名称

 Math::Units::PhysicalValue - 単位付き数値の計算


概要

use Math::Units::PhysicalValue;

my $exit  = new Math::Units::PhysicalValue "10,000 ft";
my $open  = "3500 ft";
my $delay = "43 s";

my $dist  = $exit - $open;
my $rate  = $dist / $delay;

my $weight = "180 lbs";
my $momentum = ($weight * ( ($exit - $open) / $delay )) + "0 kg*m/s";

print "$momentum\n";                     # 3,761.82 kg*m/s を出力
print ($rate + "0 miles/hour"), "\n"     # 103.07 miles/hour を出力

説明

 概要にあるように Math::Units::PhysicalValue (PV)は実世界で使用されている単位を保持して計算を行う。値と単位は別々に配列として保持される。
 演算子のオーバーロードを用いれば通常の数字の利用と同じように利用できる。これはれ列挙するよりわかりやすいと思う。混乱を避けるために値の右に常に単位を表示させておくこともできる。

my $example1 = new Math::Units::PhysicalValue "10,000 ft";  
my $example2 = "3500 ft";
my $example3 = "1000 ft";

print ($example1 + $example2 + $example3), "\n"; # 13,500 ft を出力
print ($example3 + $example2 + $example1), "\n"; # エラーとなる

 $example1 と $example2 は順番が入れ替わってもよいが、$example3 + $example2 is evaluated as the number 4500 (with no units) before it gets added to $example1 に足しこまれるまでは数値4500(単位なし)として評価されるので、不適合が起こる。

複数形に注意

 Math::Units は複数形を(ほとんどの場合)扱えるが Math::Algebra::Symbols は扱えない。

my $v1 = new Math::Units::PhysicalValue "1 hour";
my $v2 = new Math::Units::PhysicalValue "2 hours";
my $v3 = $v1 + $v2;
my $v4 = $v1 / $v2;

print "$v3\n"; # 3 hours を出力
print "$v4\n"; # 0.5 hour/hours を出力するがおそらくこんなものは望まれていないだろう

単位のエキスポート

 ショートカットがある。 Math::Units::PhysicalValue quot;PV" を用いればよい。 my $v = PV "10,000 ft" と書けば上記の $example1 と同様に用いることができる。

my $handy = (PV "8miles") + (PV "72ft");
my $time  = PV "90s";
my $fast  = $handy / $time;  # すばらしい

$StrictTypes

 現在、デフォルトでは $wierd_units = PV "5 Saxons" と書いても問題はない。何か他の単位に変換しようとしたとき Math::Units は不平を言うかもしれない。ここでの Saxon という単位は Math::Units の前にキャンセルされれば問題はないが。繰り返すが、複数形には注意すること。

$PrintPrecision

 PV の最初に Number::Format オブジェクトを指定することもできる。$PrintPrecision は PV が文字列コンテキストで評価されたときに format_number に渡される精度である。$Math::Units::PhysicalValue::PrintPrecision はデフォルトを 2 に設定されている。$Math::Units::PhysicalValue::PrintPrecision = -1 と設定すればこの条件を解除することができる。

$Math::Units::PhysicalValue::fmt = 
    new Number::Format(-thousands_sep   => '.',
                            -decimal_point   => ',',
                            -int_curr_symbol => 'DEM');

 ただしこの時にはフォーマット関数を変更する方法はない。

deunit()

 数値だけ欲しいときには deunit() を使う。

my $v = deunit PV("8 miles"); # $v = 8

0 + PV または 0 - PV

 以前に 0 に単位がなくかつそのときに限りいかなる PV 単位 も0 にするという特別な機能を2005/12/7に組み込んだ。つまり

my $v = 0 + PV("3 ft"); # $v = PV("3 ft"); 

 この関数はスカラー 0 を足す前に 0 ft に変換している。0 を足す時点でエラーを出したければまず 0 に対して単位を設定すること。

my $v = PV(0) + PV("3 ft"); # エラーになる。

著者

 Jettero Heller, <japh@voltar-confed.org>

 Jet はこのソフトウェアを自分のプロジェクトのために使っている。もしバグを見つけたら是非是非是非彼に教えてあげて欲しい。 :)
 また、どのように使っているかも教えてあげてほしい。楽しみの半分は人々が使ってくれていると知ることでもある。
 また、彼はドキュメントがカスだと認識している。支援のために彼にメールしよう。喜んでくれるだろう。


著作権

 GPL! gpl.txt を梱包しておいたからね。

 しかしこのパッケージを商用で使ってくれるとうれしい。本モジュールを使った効果を知るためになら GPL を取り去ってもいい。ばかげた条件から解放してあげる。
 本パッケージ及びその修正は GPL の条件の下でとする。利用者の書くプログラムは(どのようなちょさくけんを選ぶにせよ)、このパッケージを利用し、意図したインタフェースを組み込んだものであっても利用者のものである。


To Do

 やりたいことのリストを挙げておく。もし追加して欲しい機能があればメールが欲しい。

  1. 有効数字のサポート (実装までは $value->sci( $digits ) で対応を。)
  2. エラー送信間隔のサポート
  3. PV(0) + PV("9 m/s") はエラーでない。(私の意見では)
  4. (PV("7 m/s") ** 9) ** (1/9) はエラーではなく '7 m/s' という結果になるべき
     *) 計量単位も扱えるといい(例えば 3g == 0.003kg == 3000mg)

 計量単位について言えば、さらに悪くなるかも知れない。実際には正しく機能しているかのように見える。もし失敗例があれば知らせて欲しい。以下のところ正しく動いていると思う。


謝辞

 Math::Units 及び Math::Algebra::Symbols は非常に役に立った。

 本当に以下のみんなに感謝:
 Ken Fox <fox ta vulpes.com>
 Philip R Brenan at <philiprbrenan ta yahoo.com>
 それから Number::Format に黙礼を。いつも使っているので。
 William R. Ward, <wrw ta bayview.com>


参考資料

 perl(1), Math::Units, Math::Algebra::Symbols, Number::Format

Toolbox Logo
Updated : 2007/05/23