APL/J言語:拡張整数と有理数の計算

APL/J言語:拡張整数と有理数の計算

拡張整数(有効桁数を拡張したもの)は少数点を含む数字の最後にxを付すことによって入力できます。単項動詞x:を整数に作用することでも拡張整数を生成できます。たとえば、2つの要素からなるベクトル1234x 56x (または1234 56x)はx: 1234 56と同値です。もし引数が拡張整数なら多くの原始動詞は結果として拡張整数を生成しますが、ある種の動詞は引数が拡張整数でも結果は(正しくない)浮動少数となります。なぜなら計算結果は積分ではないからです。そのような動詞fについても、<.@fや>.@fは正しい拡張整数の結果を導きます。拡張整数同士の比較は正確でトレランス(許容度)を含みません。

   !40   NB.40の階乗:1x2x3x...x40
8.15915e47
   !40x
815915283247897734345611269596115894272000000000
   */ x: >: i.40  NB.0 1 .. 39に1を足して、拡張整数にして掛ける(*/)
815915283247897734345611269596115894272000000000
   0j_25 ": ! 2000x * i. 5 1     NB.指数フォーマット、25桁
  1.0000000000000000000000000e0    
  3.3162750924506332411753934e5735 
  1.8288019515140650133147432e12673
  2.6839997657267395961163166e20065
  5.1841810604808769398058198e27752
   ] r=: <.@%: 2 * 10 ^ 56x
14142135623730950488016887242
   ,. *: r + _1 0 1
199999999999999999999999999968972697904100132394908592081
199999999999999999999999999997256969151562033370942366564
200000000000000000000000000025541240399023934346976141049

有理数は分子と分母の形で入力することができます。分子と分母の間にrという文字を入れ、必要に応じて冒頭に符号を書きます。従って3r4は有理数の三分の四ですし、_12r5はマイナスの12割る5です。有理数は標準形式で保存、表示されます。すなわち分子と分母は約分された形(relatively prime)で、分母はプラス表示です。従って、下記のようになります。

   1r2 _1r2 2r4 2r_4 _2r_4 0r9 5 _5
1r2 _1r2 1r2 _1r2 1r2 0 5 _5

引数が有理数の場合、さまざまな動詞が自動的有理数の(正確な)結果を生成します。非有理数的な(非正確な)動詞は、有理数を生成するには不十分な有理数の引数を与えられた場合、浮動小数または複素数を生成します。(例えば%:yはyのアトムが完全な二乗数の場合に有理数を生成します。^0r1は浮動少数です。) 2つの拡張整数の商は割り切れれば拡張整数、割り切れなければ有理数です。2つの有理数の比較は正確(トレランスなし)です。引数のタイプ変換を必要とする二項動詞(例えば + - * % , = <)は、下記の表のルールに従います。

     |  B  I  X  Q  D  Z
  ---+------------------
  B  |  B  I  X  Q  D  Z     B - boolean
  I  |  I  I  X  Q  D  Z     I - integer
  X  |  X  X  X  Q  D  Z     X - extended integer
  Q  |  Q  Q  Q  Q  D  Z     Q - rational
  D  |  D  D  D  D  D  Z     D - floating point
  Z  |  Z  Z  Z  Z  Z  Z     Z - complex

例えば表現2.5+1r2において、1r2は2.5に足される前に0.5に変換され、結果は浮動少数の3になります。表現2+1r2においては、2がまず1r2に足される前に2r1に変換され、結果は有理数の5r2になります。


特に注意しなければいけないのは、、有理数と浮動少数との比較ではトラレンスが用いられ、完全な一致が求められないことです。これは有理数がまず浮動少数に変換され、浮動少数同士の比較になるからです。

動詞x:は無理数について、有理数での近似を生成します。

   2%3
0.666667
   2%3x
2r3
   (+%)/\10$1   NB.黄金率(golden mean)への浮動少数の収束
1 2 1.5 1.66667 1.6 1.625 1.61538 1.61905 1.61765 1.61818
   (+%)/\x: 10$1   NB.同じものの有理数バージョン
1 2 3r2 5r3 8r5 13r8 21r13 34r21 55r34 89r55
   |: 2 x: (+%)/\x: 10$1
1 2 3 5 8 13 21 34 55 89
1 1 2 3 5  8 13 21 34 55
   (+%)/ 100$1r1
573147844013817084101r354224848179261915075
   0j30 ": (+%)/100$1r1   NB.小数点以下30桁表示
1.618033988749894848204586834366
   H=: % @: >: @: (+/~) @: i. @ x:   NB.n次のヒルベルトマトリックス
   ] h=: H 6
  1 1r2 1r3 1r4  1r5  1r6
1r2 1r3 1r4 1r5  1r6  1r7
1r3 1r4 1r5 1r6  1r7  1r8
1r4 1r5 1r6 1r7  1r8  1r9
1r5 1r6 1r7 1r8  1r9 1r10
1r6 1r7 1r8 1r9 1r10 1r11
   -/ .* h   NB. hの行列式(determinant)
1r186313420339200000
   ~. q: % -/ .* h   NB.行列式の逆数(reciprocal)に含まれる素数
2 3 5 7 11
   i.&.(p:^:_1) 2*#h   NB.2*n以下の素数
2 3 5 7 11
   ^ 2r1   NB.^yは浮動少数もしくは複素数
7.38906
   %: 49r25   NB.%:を有理数の完全二乗数に作用させた結果は有理数
7r5
   %: 49r25 10r9
1.4 1.05409
   %: _2r1
0j1.41421       
   1 = 1+10r1^_15   NB.有理数の正確な(exact)比較
0
   (1.5-0.5) = 1+10r1^_15   NB.浮動少数の許容度あり(tolerant)比較
1
   0.5 = 1r2
1