The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

 $0 

   小数がA個与えられたら、それらがどんな共通する分母の、分数であったかの推定を
   するための数値計算プログラム。切り捨てと切り上げも仮定できるが、未指定なら四捨五入を仮定。

 出力の読み方: 
   1列目:  N  Nは共通する分母を表す。(見つかった分子候補全てとNの全てに対して、1以外の約数かあれば、ピリオドを付加。)
   2列目:  B  Nが分母と仮定した場合の、分子が整数になり得る場合の個数を数える。4通りの色で着色(最大,最大-1,最大-2,それ以外)。
   3列目以降: 
     -D の指定で、各列は与えられた数値を近似する割り算の式を表示。候補が複数ある場合は分子が最小と最大の場合を;で区切て出力。
     -I の指定で、分子になり得る数値の範囲を半区間表記で示す。整数を含む区間の場合は、緑色に着色する。
     -Q の指定で、分子となる値を列挙する。-Dや-Iよりも簡便な表示となるが、情報が落ちる場合がある。

 使用例: 
    $0 -g 50 0.25 0.33 
     # 四捨五入して、0.25 と 0.33 になるような分数で同じ分母を持つものを見つける。
     # 出力される各行の最終行が 2 となるものを探せば良い。

 オプション: 

  -c : 入力された数は、切り上げられた数であると見なす。(ceil)
  -f : 入力された数は、切り捨てられた数であると見なす。(floor)
  -g num : 何個の出力を得るかの指定。未指定なら12。"Inf" も指定可能。(get, greatest)
  -g start,num : コロンを使うと、分母をどの数から始めるかを指定が可能。(startからnum個)
  -g start,-num : numにマイナスの符号を付加すると、start から 1ずつ減少させながら 最大 num個探索する。
  -y numranges : fit値(整数を区間内に持つ対応する分子の個数)がどの値の場合に、その分母の行を出力するかを指定する。,や..を使って指定。
  -y , : fit値が最大の場合(引数として与えた割合の近似値の個数)のみ出力。( -y のパラメタは書式はやや複雑。)
  -a num : 与えられた数値との差の絶対値が num 以下である 分数表示を見つける。(実験的実装。)
  -5 2 : 既に四捨五入された値の最下位1桁をさらに四捨五入していたことを仮定する。(例. 0.45 → 0.5 → 1)
  -5 num : 既に四捨五入された値のさらに何度も最下位1桁を四捨五入したことを仮定。計num回四捨五入をしたと仮定する。
  -5 e : 偶数丸めをしたと見なす。(規格の ISO 31-0とJIS Z8401 を参照。) -5 e でなくて -5 E でも良い。
  -5 o : 奇数丸めと見なす。-5 oも可。近似したい数の最下位が5の場合に、それを落としたい場合、最下位が奇数になるようにする。
  
  -% : 入力された数はパーセンテージ表記(百分率)であると見なし、内部的には100分の1倍される。

  -D は下記約7行で説明するように、主に除算の式を出力。除算の式が作れない場合は、分子のあり得る実数範囲を暗く表示(-Iと同様)。
   -D num : 除算の式を出力。numは小数点以下の桁数。四捨五入で除算結果を出力。num=0の場合は、除算結果は見せず式のみ。
   -D num% : 除算の式を出力。%表示。numは%表示で小数点以下の桁数。四捨五入で除算結果を出力。
   -D -num : 除算の式と共に、ずれが分かるように、小数点以下num桁の誤差と共に示す。
   -D -num% : 除算の式と共に、ずれが分かるように、小数点以下num桁のパーセントと共に示す。
   -D -num%% : 除算の式と共に、ずれが分かるように、小数点以下num桁のパーミリアド(1万分の1)と共に示す。
   -D -{N}ppm :  除算の式と共に、ずれが分かるように、小数点以下num桁のppm(100万分の1)と共に示す。
   -D str1,str2 : -D でコンマがある場合は、前半は上記の説明の通りの指定に使われて、後半は該当する分子が存在しない場合のセルを埋めるのに使う。
  -I : 分子の数値を知るべくその半区間を表示す。(Interval)
  -Q : 分子の候補値全て表示。2q+1とか5q+3 など表示(qは何かの整数を意味する)。Math::Prime::Utilが導入済みなら素因数分解もする(割合の数が1個の場合)。
  -2 0 : 二次情報の出力を抑制する。
  -M 0 : ある分母に対して、全ての候補の分子が分母と同じ整数で割れる場合(≒約分可能)は、出力を抑制。

  -L 0 : 尤度比を表示しない
  -L N : 制約(合計が100%など)の個数がN個と仮定して、尤度比を算出する。

  -T testname : このプログラムのテスト。testname は1,2,3, v1,v2,v3, o1,o2,o3,o4, m1 がある。
  --help : このヘルプを表示する。(ただしPod::PerldocJp を一度インストールすると perldoc $0 でも可能。)

  補足 : 
   * 半区間とは、数学的な区間[x,y)または(x,y]のような、それぞれ、x以上y未満、x超y以下のような数全体を表す。
   * 負の数を入力に与えた場合は、その動作によく注意せよ。また 0 や 0.0 を与えた場合も動作に注意。要試行。

  開発メモ: 
     * ただ1個だけの小数点以下8桁の数が渡された場合の良いアルゴリズムを考えたい。
     * -Qの指定による出力については、さらに洗練の余地がある。
     * 最大公約数を計算するために、普段使わない Math::BigInt を用いている。
     * 入力の0に対して、-0.000が発生する謎
     * 同じ数値が与えられたときに different piece で fit も反映させたい。 -s 0 でそれを解除したい。
     * 偶数丸め ( JIS Z 8401 と ISO 31-0 ) に対応したい。-50を割り当てたい。しかし、大幅な改装が必要。
     * 各分母に対して、対数尤度を表示する -Lのオプションを作りたい。

     * "denomfind 90.5%" が意図したとおりにどうさせず。0.905と認識されなかった。90.5と認識された結果が出現し、235,236行目で数値でないという警告が出た。
     * "denomfind -% 90.5%" の動作もおかしい。0.9050 と認識された。