¥chapter{数値}

コンピューティングプロセッサ (CPU) は、コンピュータシステムの中心部であり、様々な形式の整数や浮動点小数の演算をサポートしています。プログラミング言語は、これらを, 例えばC言語の場合、char}, short}, int}, long} long long int}, float}, double}, long double}のように、異なる型で区別して利用できるようになっています。一方、Konoha は、プロセッサの性能やメモリ効率を最大利用するより、プログラミングのしやすさに力点を置いています。そのため、最も使いやすい整数と浮動小数点の形式を選んで、Int} と Float}クラスとして箱詰め(boxing)しています。本章では、これらのクラスを用いた数値の扱いを説明する。

% Integers are the most basic data type. Konoha differs from programming languages such as C and Java in that it does not make a distinction between short integers and long integers. All integers in Konoha are represented as values of the Int class. Konoha represents integers using the 64-bit integer number, which means it can represent integers ranging - to + (inclusive).

% Floating-point numbers are another basic datatype. All floating-point numbers in Konoha are represented as values of the Float class. Unlike the name implies, Konoha represents floats using the 64-bit floating-point format defined by the IEEE 745 standard, called double in C, C++, and Java.

== 数値と型}

Konohaは、２種類の数値表現をサポートしています。これらは、C言語における64ビット符号付き整数(long long int) と倍精度浮動小数点数(double)に相当し、日常的な利用においては自然数や実数を表現するのに十分な値域と精度を持っています。

Konohaでは、``Everything is an Object''の設計であり、数値を含め、すべての値はオブジェクトとなっています。Int}クラスとFloat}クラスは、それぞれ整数値と浮動小数点数値を箱詰め(boxing)してインスタンス化するためのクラスです。
 
{{{
>>> (1).class
Int
}}}

注意：「箱詰め(boxing)」の話だけをすると、プログラミング言語実装に詳しい方は不安になるだろう。Konohaの内部をより正確にいえば、オブジェクトとしてアクセスするときのみ、boxingされており、それ以外は、もちろん unboxing された状態で数値処理されています。不必要なメモリ消費は最低限に抑えられています。

=== int}, float}型}

Konoha では、クラス名は英大文字で始まり、そのまま型名として用いられる。このルールにしたがえば、整数値、浮動少数点値を用いるための型は、Int}, Float}型となります。しかし、C/C++, Java など、ほとんどすべてのプログラミング言語において、これらの型はint}, float}のように英小文字で始まっています。

ここで、言語設計の統一的美しさにこだわれば、Konohaのルールにしたがってもらえばよいものであるが、「言語」というものは実際に使っている人たちが主人公です。プログラミング言語も、そろそろ半世紀の歴史をもつわけであるから、言語設計者が好き勝手に文法を決められる時代はもう終わったと考えてよいだろう。統一的な美しさはないが、Konohaでは、int} や float}も別名定義し、プログラム中で利用することができます。

最後に、Konoha風のInt}と伝統的なint}のどちらを使った方がよいかという問題が残る。Konohaのローカルルールに固執してInt}/Float}を使うより、C/C++やJavaなどとソースコードの交換性を保つため、int}/float}を使う方がよいと考える。また、同じ理由で long}やdouble}型も定義されており、Int}/Float}の別名として定義されています。

=== Decimal**}

将来、小数点以下の精度を保持した無限長の数値をサポートすることを計画しています。

== 数値リテラル}

数値は、ふつうに表記すれば、アルファベットで始まる予約語や識別子と容易に区別がつけられる。そのため、数値リテラルと言っても、極めて自然な表記であるが、整数と浮動小数点を区別するため、表記上のルールがあります。

=== 整数リテラル}
%3.2.1   Integer Literals
%In a Konoha program, a base-10 integer is written as a sequence of digit. For example:

スクリプティング言語では、short}やlong}などサイズの異なる整数を使い分ける用途はあまり想定しにくく、単純に自然数を表現するために整数を用いることが多い。Int}クラスでは、数値の上限下限を最も気にしなくて済む64ビット整数¥footnote{KNH_USING_INT32|オプションを用いれば、32ビット整数に変更することも可能です。}を採用しています。

Konohaでは、10進数の整数は、数字の列として書ける。
整数の値の範囲は、-9,223,372,036,854,775,807から9,223,372,036,854,775,807となります。
つまり、日常の利用ではまず足りなくなる心配のない値域をカバーしています。

{{{
0
3
100000000
}}}

%3.2.2   Hexadecimal and Binary Literals
%In addition to base-10 integer literals, Konoha recognizes hexadecimal (base-16) values. A hexadecimal literal begin with "0x" or "OX", followed by a string of hexadecimal digits, one of digits 0 through 9 or the letters a (or A) through f (or F), which represent values 10 through 15. Here are examples of hexadecimal integer literals:

10進数表記に加えて、Konoha は、16進表記と2進表記をサポートしています。16進表記の整数リテラルは、0x|もしくは0X|で始まり、続いて数字(0-9)もしくは10から15までの数字を表す英字(A-F)が続く形式です。

{{{
0xff                             // 15 * 16 + 15 = 255
0xCAFE911
}}}

%In addition to hexadecimal literals, Konoha allow you to specify integer literals in binary (base-2) format. An binary literal begins with "0b" or "OB" and is followed by a sequence of digits, each 0 or 1. For example:

クラスルームでは、結構、2進数の説明も頻出する。そのため、Konohaは独自の2進数リテラルとして、0b| もしくは、0B|から始まり、0もしくは1が続く2進数で整数を与えることができます。

{{{
0b1111                           // 0xff = 255 
}}} 

=== Float リテラル}
%3.3   Floating-Point Numbers
%3.3.1   Floating-Point Literals

% Floating-point numbers are another basic datatype. All floating-point numbers in Konoha are represented as values of the Float class. Unlike the name implies, Konoha represents floats using the 64-bit floating-point format defined by the IEEE 745 standard, called double in C, C++, and Java.

浮動小数点数(floating-point numbers) は、全て Float}クラスの値として表現される。その名前から想像されるものとは異なり、IEEE 745 標準で定義された64ビット倍精度形式を用いています。これらは、C/C++, Java言語では、通常 double}型で表現される形式です。

% Floating-point literals can have a decimal point; they use the traditional syntax for real numbers. A real value is represented as the integral part of the number, followed by a decimal point and the fractional part of the number.

Float リテラルは、小数点を必ず含む。通常、整数パートの数列に始まり、小数点、続いて小数点以下の数列が続く形式です。また、eもしくはEによって$10 ^ n$乗形式の位を追加することも可能です。

% Floating-point literals may also be represented using exponential notation: a real number followed by the letter e (or The E), followed by an optional plus or minus sign, followed by an integer exponent. This notation represents the real number multiplied by 10 to the power of the exponent.More succinctly, the syntax is: [digits][.digits][(E|e)[(+|-)]digits]

{{{
3.14
2345.789
.33333333333
6.02e23
1.473E-32
}}}

%Note that there are infinitely many real numbers, but only a finite number of them (, to be exact) can be represented exactly by the Konoha floating-point format.

=== 桁取り表記}

我々は、日常、大きな数字を間違えることなく扱うため、1000桁ごとにカンマ(,)を入れて表記することが多い。プログラミング言語では、カンマは特殊な意味をもった演算子の一種として扱われるが、Konohaでは、アンダースコア(_|)を数値リテラルの任意の箇所に入れることが認められ、カンマの代わりに桁取り表記も可能となります。OCaml風の拡張であるが、ちょっとだけ読みやすくなります。

{{{
1_0000
9_223_372_036_854_775_807
}}}

=== 意味タグ拡張と単位*}

Konohaは、セマンティックプログラミングの機能として、Int}やFloat}クラスに対して意味タグを付加することができます。意味タグは、単位など直感的なタグを用いることが可能であり、数値リテラルの後置辞として利用することができます。詳しくは、「第 ¥ref{semantic_programming}章 セマンティックプログラミング」で解説する。

{{{
32.195km                         // Float:km 
80[km/h]                         // Int[80/km]
}}}

注意：意味タグが定義されていないときは、意味タグは無視されて、通常の整数、浮動小数点数のリテラルとして扱われる。型チェックはおこなわれないが、読みやすさのために意味タグを使っても構いません。

== 数値演算}

Konohaでは、数値はクラスによって箱詰めされているが、その値はそのままネイティブの数値表現、C言語で言うところの long long int と doubleです。したがって、その数値演算の振る舞いは、C言語の演算子と同じです。特に、浮動小数点演算において計算結果が微妙に異なることがバグレポートとして報告されるが、そもそも浮動小数点演算というのは桁落ち、丸め誤差などが含まれていることを思い出して欲しい。

=== 四則演算}

Int}, Float}は、それぞれの型の範囲において四則演算(+,-,*./)を定義しています。つまり、Int}型間の演算ではInt}型の結果がえられ、Float}型間の演算では、結果はFloat}型になります。

{{{
>>> 7 / 2                  // Int型の除算
3
>>> 7.0 / 2.0              // Float型の除算
3.5000000
}}}

一方、Int}型とFloat}型を混在して演算したときは、Int}型の値は全て自動的にFloat}型に変換されたのち、演算される。したがって、結果はFloat}型となります。

{{{
>>> 7 / 2.0               // 7は7.0へ
3.5000000
>>> 7.0 / 2               // 2は、2.0へ
3.5000000
}}}

ゼロ除算の場合は、Int}, Float}ともに、Arithmetic!!|例外が通知される。

{{{
>>> 1 / 0                 // ゼロ除算
Arithmetic!!: Zero Divide
}}}

¥subsubsection{優先順位}

Konoha の四則演算は、日常の数学の演算と同じ順序で計算される。つまり、乗算と除算は、加算と減算に優先して実行される。演算の優先順位を変更するときは、優先対したい演算を()で囲む。

{{{
>>> 1 + 2 * 3
7
>>> (1 + 2) * 3
9
}}}

Konohaでは、四則演算以外にも数多くの演算子をサポートしています。これらを混在して利用するときは、優先する演算子を()で囲む習慣をつけると、思わぬ誤動作を防ぎ、また読みやすさも向上する。

=== ビット演算}

Konohaは、Int}型の数値のみ、ビット演算をサポートしています。

{{{
>>> %bits(1)
00000000 00000000 00000000 00000001
>>> %bits(‾1)
11111111 11111111 11111111 11111110
>>> %bits(2)
00000000 00000000 00000000 00000010
>>> %bits(1&2)
00000000 00000000 00000000 00000000
>>> %bits(1|2)
00000000 00000000 00000000 00000011
>>> %bits(1<<4)
00000000 00000000 00000000 00010000
>>> 
}}}

スクリプティング言語では、低レベルな処理を書く機会が少ないため、ビット演算子を活用する機会は少ない。さらに、Konoha では、ビット演算子の記法は他のよく使われるオペレータ(¥verb#|a|#yやOUT << "hi"|など)に転用されているため、演算子の優先度がC/C++, Java と異なることがあります。この違いを覚えるよりは、ビット演算子と四則演算子を組み合わせるときは、()|で囲んで優先する演算子を明示した方がよい。

{{{
>>> %bits(1+1<<2)                    // 優先度が？
00000000 00000000 00000000 00001000
>>> %bits(1+(1<<2))
00000000 00000000 00000000 00000101
>>> %bits((1+1)<<2)
00000000 00000000 00000000 00001000
}}}

¥index{Float@Float.floatToIntBits}  ¥index{Float@Float.intBitsToFloat}
Floatの数値をIEEE 754 浮動小数点のビットレイアウトにしたがってビット演算をしたいときは、
まずFloat.floatToIntBits()|を用いてInt}型へ変換したのち、Float.intBitsToFloat()|でFloat}型に変換することで可能になります。ちなみに、Konohaは32ビットシステムであっても、Int}とFloat}はともに64ビットで表現される。

{{{
>>> n = (float)1.0;                 // 数値変換
>>> %bits(n)
00000000 00000000 00000000 00000001
>>> f = Float.floatToIntBits(1.0)   // ビットレイアウト維持
>>> %bits(f)
00111111 11110000 00000000 00000000
}}}

=== 比較演算}

Int}型, Float}型は、ともに比較演算子(==|, !=|, <|, <=|, >=|, >|)によって数値を比較できます。また、Int}型、Float}型の比較を混在して用いたとき、Konohaは通常、異なる型の比較はオブジェクトIDによる比較になるが、特別に自動的にIntクラスをFloatクラスに変換して比較を行う。

{{{
>>> 1 < 2.0
true
>>> 3.2 != 3
false
}}}

Int}型の比較演算子は、実用上問題がおこらないが、Float}型の場合は、IEEE754規格に基づいた表現のため、実用上は同値であっても同値とみなされない。そこで、(正規表現のための)マッチング演算子=‾|を用いると、簡単にほぼ等しいを演算することができます。有効桁数は、小数点以下5桁です。

{{{
>>> 1.00003 == 1.0
false
>>> 1.00003 =‾ 1.0
true
}}}

=== 数値変換}

Konohaでは、Int型とFloat型の型変換は、必要に応じて自動的に行われる。これらを明示的におこないたい場合は、キャスト演算を用いることができます。ただし、Konohaの数値変換の振る舞いは、C言語の数値変換の振る舞いに基づいています。特に、Float}からInt}への変換は、切り捨てになるため注意が必要です。

{{{
>>> (int)1.8
1
>>> (int)-1.8
-1
}}}

¥index{Math@Math.ceil} ¥index{Math@Math.round}, ¥index{Math@Math.floor}
小数点以下 n 桁で切り上げ、四捨五入、切り下げを行いときは、math}パッケージのクラス関数Math.ceil()|, Math.round()|, Math.floor()|を用います。

{{{
>>> using math.*;
>>> Math.ceil(1.8)
2.0000000
>>> Math.round(1.8)
2.0000000
>>> Math.floor(1.8)
1.0000000
}}}

=== 文字列との変換}

Konohaは、全てのクラス間の変換がキャスト演算子に統合されています。文字列への変換も文字列からの変換もキャストで行うことができます。ただし、数値の書式を指定したい場合は、次節のフォーマッタを用います。

{{{
>>> (String)1.8
"1.8000000"
>>> (int)"123"
123
}}}

文字列から数値への変換は、数値リテラルの文法も解釈される。

{{{
>>> (int)"1"
1
>>> (int)"0xff"
255
>>> (float)"6.0221415e23"
602214149999999896780800.000000
}}}

数値以外の文字列は、それぞれInt}型、Float}型のデフォルト値へ変換される。デフォルト値の代わりに（変換に失敗したことを知るために）null}を得たいときは、Nullable キャストを用いることができます。

{{{
>>> (int)"hello,world"         // 数値でない
0
>>> (int?)"hello,world"        // 数値でない
null
}}}

== 数値フォーマッタ}

数値フォーマッタは、C言語printf|書式に由来しているものが多いが、独自に定義されたものは%bits|などいくつか存在する。ここでは、代表的な数値フォーマッタについて紹介する。

=== 10進書式 ¥%d}

10進数(digit)書式では、文字列の幅$m$ を$%|m{¥tt d}$のように指定できます。
また、$%|0m{¥tt d}$ように書式を与えると、空白の代わりに0で埋められる。（これは、数値としての順序が文字列化したときも保持されるため、よく用いられる。）

{{{
>>> %d(123)                    
"123"
>>> %4d(123)                    // 幅(4)を指定
" 123"
>>> %-4d(123)                   // 左寄せ
"123 "
>>> %04d(123)                   // 0パディング
"0123"
}}}

=== 16進書式 ¥%x}

10進数(digit)書式では、10進書式同様に、文字列の幅$m$ を$%|m{¥tt x}$のように指定できます。

{{{
>>> %x(123)                    
"7b"
>>> %8x(123)                   // 文字列の幅 8
"      7b"
>>> %08x(123)                  // 0パディング
"0000007b"
}}}

=== 小数書式 ¥%f}

小数書式は、Float}クラスだけでなく、Int}クラスもサポートしています。したがって、整数も型変換することないしに、小数書式でフォーマッティング可能です。

{{{
>>> %f(1)
1.000000
>>> %f(1.0)
1.000000
}}}

小数書式では、全体の幅$m$ と小数点以下の桁数$n$を$%|m.n{¥tt f}$のように指定できます。

{{{
>>> %f(3.14159)
"3.141590"
>>> %6.2f(3.14159)             // 小数点以下2桁
"  3.14"
>>> %6.3f(3.14159)             // 小数点以下3桁
" 3.142"
}}}

=== ビット書式 ¥%bits}

ビット書式は、printf}書式に存在しない独自の書式です。整数や浮動小数点数のビットレイアウトを確認するために導入されており、クラスルーム用途の書式です。

{{{
>>> %bits(-1)                    // 2の補数表現 :)
11111111 11111111 11111111 11111111
}}}

=== UCS4文字書式 ¥%c}

文字書式は、printf}書式でもおなじみの書式であり、整数から文字コードを用いて文字に変換してくれる。ただし、Konoha 言語では、Unicode文字コード(UCS4)を用いているため、ASCII 文字コード以外の文字も変換することができます。

{{{
>>> %c(30)                       // ASCII (<128)
"A"
>>> %c(0x3042)                   // UCS4  (>128)
"あ"
}}}

== 乱数生成}

¥index{Int.random} ¥index{Float.random}

乱数生成は、Int}とFloat}クラスの値をランダムに生成する一種のコンストラクタです。Konoha では、標準乱数生成器として、統計処理分野で愛用される高品質な疑似乱数アルゴリズム Mersenne Twister ¥cite{mt} を採用しています。

乱数生成は、クラス関数として提供されています。Int.random(n)|は、0からn|(含まれない)までの整数乱数を生成し、Float Float.random()|は、浮動小数点乱数x ($0.0 < x < 1.0$)を生成するクラス関数です。

例えば、さいころ(1〜6)を作りたいときは、次のように用いることができます。

{{{
>>> Int.random(6) + 1           // さいころ
3
>>> Int.random(6) + 1           // 違う目が出た
6
}}}
n
=== 乱数生成器の初期化}
¥index{System.setRandomSeed}

Konohaは、起動時の時刻とラインタイム情報から起動する度に乱数生成器を初期化しています。そのため、通常、乱数生成器を初期化する必要はない。ただし、明示的に乱数生成器を初期化したいときは、System.setRandomSeed(seed)|を用いることで、再初期化可能です。(パラメータseed|に対し、0を与えたときのみ、その時刻とランタイム情報からシードが生成される。)

{{{
>>> System.setRandomSeed(1)　  // 初期化 
>>> Int.random()               // 初期化後は同じ　 
1234794094773155764
}}}

注意：同じ seed 値で初期化すると、乱数生成系列が同じになります。つまり、毎回、同じ順番で同じ乱数生成が繰り返される。ただし、Konoha の乱数生成器は、複数の言語エンジン/スレッドから共有されているため、マルチ言語インスタンスやスレッド実行下での乱数生成は、逆に同一性は保証されなくなります。

