APL/J言語:数字(ナンバー)

APL/J言語:数字(ナンバー)

J言語で扱う数字(ナンバー)は、6種類あって、ブール型、整数、実数(リアル)、複素数、拡張整数(任意の桁数の数字)、有理数(拡張整数のペア)です。
関連して、特殊数字(無限と不確定数)、表記法、表示、ランダム数についても述べます。

   a=:'0=0';'37';'2.5';'1.23457e10'
   b=:(datatype 0=0);(datatype 37);(datatype 2.5);(datatype 1.23456e10)
   a ,: b
 +-------+-------+--------+----------+
 |0=0    |37     |2.5     |1.23457e10|
 +-------+-------+--------+----------+
 |boolean|integer|floating|floating  |
 +-------+-------+--------+----------+
   b=: '1j1' ; '2r3' ; 'o.1' ; '^1'
   (b ,: (".&.>) b) , ((datatype&".)&.>) b
 +-------+--------+--------+--------+
 |1j1    |2r3     |o.1     |^1      |
 +-------+--------+--------+--------+
 |1j1    |2r3     |3.14159 |2.71828 |
 +-------+--------+--------+--------+
 |complex|rational|floating|floating|
 +-------+--------+--------+--------+

ブール型演算子は以下のとおり。

   and    =: *.
   or     =: +.
   not    =: -.
   notand =: *: 
   notor  =: +:

実数(リアル、浮動少数)の比較は、差異が相対的に小さい場合(2^_44以下の場合)同等とされる。つまりaとbの差が0でなくてもa=bが正となる。

   str,:(".&.>)str=:'a =: 1.001';'b =: a - 2^_45';'a - b';'a = b'
 +----------+--------------+-----------+-----+
 |a =: 1.001|b =: a - 2^_45|a - b      |a = b|
 +----------+--------------+-----------+-----+
 |1.001     |1.001         |2.84217e_14|1    |
 +----------+--------------+-----------+-----+

相対的になので、ゼロはどんな小さい数とも同等にはならない。


複素数(complex number)、虚数(imaginary number)は3j4、0j1というように表記される。

   a ,: (".&.>) a=:'i =: %: _1';'i * i';'0j1 * 0j1'
 +----------+-----+---------+
 |i =: %: _1|i * i|0j1 * 0j1|
 +----------+-----+---------+
 |0j1       |_1   |_1       |
 +----------+-----+---------+

j.(ジェイドット)という動詞によって作ることもできる。

    a ,:(".&.>) a=:'3 + (%: _1) * 4';'3 j. 4'
 +---------------+------+
 |3 + (%: _1) * 4|3 j. 4|
 +---------------+------+
 |3j4            |3j4   |
 +---------------+------+
   a,:(".&.>) a=:'2j3 * 5j7';'10j21 % 5j7';'2j3 % 2' 
 +---------+----------------+-------+
 |2j3 * 5j7|10j21 % 5j7     |2j3 % 2|
 +---------+----------------+-------+
 |_11j29   |2.66216j0.472973|1j1.5  |
 +---------+----------------+-------+

複素数3j4のような数はスカラーである。複素数スカラーに+.(プラスドット)を作用させると実数部分と虚数部分を別々に取り出すことができる。*.(アスタリスク)を作用させると、大きさと角度(ラジアン)を取り出すことができる。

   a,:(".&.>) a=:'+. 3j4';'*. 3j4' 
 +------+----------+
 |+. 3j4|*. 3j4    |
 +------+----------+
 |3 4   |5 0.927295|
 +------+----------+

大きさと角度が与えられれば、サイン(sine)とコサイン(cosine)を持ちいて複素数を作ることができる。そのための関数r.(アールドット、ポーラー)がある。

   sin =: 1 & o.
   cos =: 2 & o.
   mag =: 5
   ang =: 0.92729522  NB.ラジアン
   a,:(".&.>)a=:'mag * (cos ang) + 0j1 * sin ang';'mag r. ang' 
 +-------------------------------+----------+
 |mag * (cos ang) + 0j1 * sin ang|mag r. ang|
 +-------------------------------+----------+
 |3j4                            |3j4       |
 +-------------------------------+----------+

大きさXで角度(ラジアン)Yの複素数をXarYと書くことができる。X r. Yと書くのと同等である。もし角度が度数で与えられている場合、XrdYと書くことができる。

   a,:(".&.>)a=:'5ar0.9272952';'5ad53.1301' 
 +------------+----------+
 |5ar0.9272952|5ad53.1301|
 +------------+----------+
 |3j4         |3j4       |
 +------------+----------+


拡張整数は通常17桁の浮動少数を桁数に関係なく拡張したもので、数字のあとにxを付して表す。

   c,:(".&.>) c=:'a =: *: 10000000001';'b =: *: 10000000001x' 
 +-------------------+---------------------+
 |a =: *: 10000000001|b =: *: 10000000001x |
 +-------------------+---------------------+
 |1e20               |100000000020000000001|
 +-------------------+---------------------+
   d,:(".&.>)d=:'datatype a';'datatype b' 
 +----------+----------+
 |datatype a|datatype b|
 +----------+----------+
 |floating  |extended  |
 +----------+----------+
   e,:(".&.>)e=:'(a + 1) - a';'(b + 1) - b'
 +-----------+-----------+
 |(a + 1) - a|(b + 1) - b|
 +-----------+-----------+
 |0          |1          |
 +-----------+-----------+


有理数は二つの拡張整数の比でたとえば3分の2ならば2r3と書く。

   a,:(".&.>)a=:'2r3 + 1r7';'2r3 * 4r7';'2r3 % 5r7' 
 +---------+---------+---------+
 |2r3 + 1r7|2r3 * 4r7|2r3 % 5r7|
 +---------+---------+---------+
 |17r21    |8r21     |14r15    |
 +---------+---------+---------+
   a,:(".&.>)a=:'2 % 3';'2x % 3x'
 +--------+-------+
 |2 % 3   |2x % 3x|
 +--------+-------+
 |0.666667|2r3    |
 +--------+-------+
   a,:(".&.>)a=:'x: 0.3';'x: 1 % 3x'
 +------+---------+
 |x: 0.3|x: 1 % 3x|
 +------+---------+
 |3r10  |1r3      |
 +------+---------+
   a,:(".&.>)a=:'float =: x: ^: _1';'float 2r3' 
 +-----------------+---------+
 |float =: x: ^: _1|float 2r3|
 +-----------------+---------+
 |                 |0.666667 |
 +-----------------+---------+

有理数の分子と分母は2 & x:で取り出せる。結果は長さ2のリストである。

   a,:(".&.>)a=:'nd =: 2 & x:';'nd 2r3' 
 +------------+------+
 |nd =: 2 & x:|nd 2r3|
 +------------+------+
 |            |2 3   |
 +------------+------+

タイプコンバージョンはある程度自動で(より精度の高いタイプへ)変換される。

   a,:(".&.>)a=:'1 + 10^19x';'1r3 * 0.75' 
 +--------------------+----------+
 |1 + 10^19x          |1r3 * 0.75|
 +--------------------+----------+
 |10000000000000000001|0.25      |
 +--------------------+----------+
   a,:(".&.>)a=:'datatype 1r3';'datatype 1%3';'z =: 1r3, 1%3';'datatype z'
 +------------+------------+-----------------+----------+
 |datatype 1r3|datatype 1%3|z =: 1r3, 1%3    |datatype z|
 +------------+------------+-----------------+----------+
 |rational    |floating    |0.333333 0.333333|floating  |
 +------------+------------+-----------------+----------+


浮動少数は1e308がコンピューターの限度でそれ以上の数が結果となるような演算の結果は特殊な数字_(アンダーバー、アンダースコア、無限)となる。負の無限は__(アンダースコアアンダースコア)となる。無限(インフィニティ)のタイプは浮動少数である。

   a,:(".&.>)a=:'1e308 * 0 1 2';'1e400';'1 % 0'
 +-------------+-----+-----+
 |1e308 * 0 1 2|1e400|1 % 0|
 +-------------+-----+-----+
 |0 1e308 _    |_    |_    |
 +-------------+-----+-----+
   datatype _
floating


その他

   a,:(".&.>)a=:'pi =: 1p1';'twopi =: 2p1';'2p_1' 
 +---------+------------+-------+
 |pi =: 1p1|twopi =: 2p1|2p_1   |
 +---------+------------+-------+
 |3.14159  |6.28319     |0.63662|
 +---------+------------+-------+
   o.1
3.14159
   a,:(".&.>)a=:'e =: 1x1';'2x_1';'2 * e ^ _1' 
 +--------+--------+----------+
 |e =: 1x1|2x_1    |2 * e ^ _1|
 +--------+--------+----------+
 |2.71828 |0.735759|0.735759  |
 +--------+--------+----------+
   ^1
2.71828
   2b101 
5
   a,:(".&.>)a=:'16bff';'(16 * 15) + 15' 
 +-----+--------------+
 |16bff|(16 * 15) + 15|
 +-----+--------------+
 |255  |255           |
 +-----+--------------+
   a,:(".&.>)a=:'10b0.9';'20b0.f'
 +------+------+
 |10b0.9|20b0.f|
 +------+------+
 |0.9   |0.75  |
 +------+------+
   1r2p1
1.5708
   a,:(".&.>)a=:'1.2e2';'(1.2e2) % 4';'1.2e2r4' 
 +-----+-----------+-------+
 |1.2e2|(1.2e2) % 4|1.2e2r4|
 +-----+-----------+-------+
 |120  |30         |30     |
 +-----+-----------+-------+
   a,:(".&.>)a=:'3r4';'0.75j5';'0.75j5' 
 +---+------+------+
 |3r4|0.75j5|0.75j5|
 +---+------+------+
 |3r4|0.75j5|0.75j5|
 +---+------+------+
   a,:(".&.>)a=:'3j4p5';'(3j4) * pi ^ 5'
 +---------------+---------------+
 |3j4p5          |(3j4) * pi ^ 5 |
 +---------------+---------------+
 |918.059j1224.08|918.059j1224.08|
 +---------------+---------------+
   a,:(".&.>)a=:'(3*pi)+5';'1p1b3'
 +--------+-----+
 |(3*pi)+5|1p1b3|
 +--------+-----+
 |14.4248 |3    |
 +--------+-----+


フォーマット動詞":(ダブルクオートコロン、フォーマット)は単項動詞としては数値を文字列に変換する。見かけは変化ない。

   c,:(".&.>)c=:'a =: 1 % 3';'": a';'$ ": a' 
 +----------+--------+------+
 |a =: 1 % 3|": a    |$ ": a|
 +----------+--------+------+
 |0.333333  |0.333333|8     |
 +----------+--------+------+
   d,:(".&.>)d=:'b =: 1 % 3 4';'": b';'$ b';'$ ": b' 
 +-------------+-------------+---+------+
 |b =: 1 % 3 4 |": b         |$ b|$ ": b|
 +-------------+-------------+---+------+
 |0.333333 0.25|0.333333 0.25|2  |13    |
 +-------------+-------------+---+------+

二項動詞としては左側引数に複素数をとり、8j4ならば幅8桁の数字で小数点以下4桁になる。0j3のように幅0を指定すると幅は変動になる。10j_3のように小数点以下がマイナスだとeを用いた表現になる。

   a,:(".&.>)a=:'c =: % 1 + i. 2 2';'w =: 8j4 ": c';'$ w' 
 +-----------------+----------------+----+
 |c =: % 1 + i. 2 2|w =: 8j4 ": c   |$ w |
 +-----------------+----------------+----+
 |       1  0.5    |  1.0000  0.5000|2 16|
 |0.333333 0.25    |  0.3333  0.2500|    |
 +-----------------+----------------+----+
   a,:(".&.>)a=:'c';'0j3 ": c';'10j_3 ": c' 
 +-------------+-----------+--------------------+
 |c            |0j3 ": c   |10j_3 ": c          |
 +-------------+-----------+--------------------+
 |       1  0.5|1.000 0.500| 1.000e0   5.000e_1 |
 |0.333333 0.25|0.333 0.250| 3.333e_1  2.500e_1 |
 +-------------+-----------+--------------------+  

ランダム数は?(クエスチョンマーク、ロール)を用いる。

   ? 6
4
   ? 6 6 6 6
3 4 5 2
   ? 4 $ 6
2 3 5 3

右側引数を0(ゼロ)にすると0から1の間のランダム数が返される。

   ? 0 0 0 0
0.14112615 0.083891464 0.41388488 0.055053198


正規分布などはライブラリースクリプトstatdist.ijsを用いる。
平均が0で標準偏差1の実数はnormalrandを用いる。

   require 'statdist'

   normalrand 6
0.84096966 0.59389446 1.5530828 0.69271405 0.87141049 _0.53649589

二項動詞として?(クエスチョンマーク、ディール)をもちいるとx ? yだとi.yのなかから重複なしにx個が選ばれる。

   13 ? 52
28 46 4 24 19 27 5 12 10 13 49 21 42

   4 13 $ 52 ? 52
25 12  1 14 37 29 43 33 27  5 11 26 47
49 23 50  9 39  4 51 18 38 22 19  8  0
24 36 32 10 13 16  6 48 20 42 28 30  3
15 31 21 40  2 45 17 41 35 46  7 44 34