標準 Pascal と数

# はじめに

標準 Pascal と数についてのおさらいです (ちょびっと Delphi)。

# 数

自然数 (ℕ) は整数 (ℤ) に含まれ、整数は有理数 (ℚ) に含まれ、有理数は実数 (ℝ) に含まれます (ℕ⊂ℤ⊂ℚ⊂ℝ)。


## ■ 自然数 (Natural Number)

### 一般

| 加算 | 減算 | 乗算 | 除算 |
|:---:|:---:|:---:|:---:|
| 〇 | △ | 〇 | △ |

 - 1 (または 0) から始まる順序を表す数
 - 正の整数
 - 記号は ℕ
 - 自然数同士の四則演算では加算と乗算が完全に可能
 - 負数 (または 0) が扱えないため、減算を行えない事がある
 - 小数を扱えないため、除算を行えない事がある
 - コンピュータでは **符号なし整数型 (unsigned integer type)** で扱える

### Pascal

 - 標準 Pascal に符号なし整数型はないため、**整数型 (Integer)** か **部分範囲型** で扱う
 - 次の数 (successor) を表す順序型関数 `Succ()` が用意されている
 - 順序値を表す順序型関数 `Ord()` が用意されている

例えば byte 型 (UInt8) は部分範囲型を使って次のように定義する事ができます。

```pascal
type
  byte = 0..255;
```

標準 Pascal の場合、次の順序値が存在しない場合に順序型関数 `Succ()` はエラーを返しますが、Delphi だとエラーにならない事があります。次のコードは Delphi だと 0 が表示されます。

```pascal
program SuccTest(output);
type
  byte = 0..255;
var
  v: byte;
begin
  v := 255;
  v := Succ(v);
  Writeln(v);
end.
```

コンパイラ指令 `{$R+}` で範囲チェックを行うようにすれば実行時エラーになります。

```pascal
program SuccTest(output);
{$R+}
  ...
```

:::note info
Delphi には Byte 型をはじめとした符号なし整数型が複数用意されています。
:::

**See also:**

 - [自然数 (Wikipedia)](https://ja.wikipedia.org/wiki/%E8%87%AA%E7%84%B6%E6%95%B0)
 - [範囲チェック (DocWiki)](https://docwiki.embarcadero.com/RADStudio/ja/%E7%AF%84%E5%9B%B2%E3%83%81%E3%82%A7%E3%83%83%E3%82%AF)
 - [単純型 (DocWiki)](https://docwiki.embarcadero.com/RADStudio/ja/%E5%8D%98%E7%B4%94%E5%9E%8B%EF%BC%88Delphi%EF%BC%89)


## ■ 整数 (Integer)

### 一般

| 加算 | 減算 | 乗算 | 除算 |
|:---:|:---:|:---:|:---:|
| 〇 | 〇 | 〇 | △ |

 - 1 に 1 ずつ足した数と 1 ずつ引いた数
 - 記号は ℤ
 - 整数同士の四則演算では加算、減算、乗算が完全に可能
 - 小数を扱えないため、除算を行えない事がある
 - コンピュータでは **符号付き整数型 (integer type)** で扱える

### Pascal

 - 標準 Pascal では **整数型 (Integer)** で扱う
 - 整数型は **単純型 (Simple types)** の一種で、**順序型 (Ordinal types)** の一種
 - 整数除算 (商のみを返す) を行うための演算子 **div** が用意されている
 - 剰余を求める演算子 **mod** が用意されている
 - 前の数 (predecessor) を表す順序型関数 `Pred()` が用意されている
 - 整数の最大値を示す定数 `maxint` が用意されている

**See also:**

 - [整数 (Wikipedia)](https://ja.wikipedia.org/wiki/%E6%95%B4%E6%95%B0)


## ■ 有理数 (Rational Number)

### 一般

| 加算 | 減算 | 乗算 | 除算 |
|:---:|:---:|:---:|:---:|
| 〇 | 〇 | 〇 | 〇 |

 - 整数の比 (レシオ) で表す事の出来る実数
 - 一般的には分数
 - 記号は ℚ
 - 有理数同士の四則演算はすべて完全に可能 [^1]
 - コンピュータでは **実数型 (real data type)** で扱う事になる

### Pascal

 - (特になし)


**See also:**

 - [有理数 (Wikipedia)](https://ja.wikipedia.org/wiki/%E6%9C%89%E7%90%86%E6%95%B0)


## ■ 実数 (Real Number)

### 一般

| 加算 | 減算 | 乗算 | 除算 |
|:---:|:---:|:---:|:---:|
| 〇 | 〇 | 〇 | 〇 |

 - 一般的な数 (有理数と[無理数](https://ja.wikipedia.org/wiki/%E7%84%A1%E7%90%86%E6%95%B0))
 - 記号は ℝ
 - 実数同士の四則演算はすべて完全に可能 [^1]
 - コンピュータでは **実数型 (real data type)** で扱える

### Pascal

 - 標準 Pascal の実数型である **Real 型**は 48bit [^2]
 - 実数型は **単純型 (Simple types)** の一種
 - 実数型に整数値を格納する事は可能 (ℤ⊂ℝ)
 - 整数型に実数値を格納するには変換関数を使い、小数部の処理方法を指定する必要がある
 - 実数型を整数型に丸める `Round()` 関数が用意されている
 - 実数型を整数型に切り捨てる `Trunc()` 関数が用意されている
 - 実数は指数表現で表す事もできる (ex. `5e-8`)

:::note info
Pascal の古い仕様では Real 型は実数の部分集合という扱いでした。概念的にはそうなのでしょうが、Pascal の集合型ではどうやっても Real 型と同等な型を定義できません。コンピュータのリソースには限りがありますからね。
:::

**See also:**

 - [実数 (Wikipedia)](https://ja.wikipedia.org/wiki/%E5%AE%9F%E6%95%B0)


# おわりに
数について学ぶと、標準 Pascal にあるルーチンや演算子の存在する理由がなんとなく解ります。

標準 Pascal には複素数 (ℂ) を計算するための機能が備わっていません。

 - 『[コンピュータアルゴリズム辞典](https://qiita.com/ht_deko/items/06946a72b51f577523bb#12-%E3%82%B3%E3%83%B3%E3%83%94%E3%83%A5%E3%83%BC%E3%82%BF%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0%E4%BA%8B%E5%85%B8)』には Pascal で書かれた複素数を計算するアルゴリズムが掲載されています
 - Delphi には複素数 (ℂ) の計算を行うためのルーチンが格納された `System.VarCmplx` ユニットが用意されています


**See also:**

 - [標準 Pascal 範囲内での Delphi 入門 (Qiita)](https://qiita.com/ht_deko/items/e2796788c65c2cda1de5)
 - [Delphi と複素数 (Qiita)](https://qiita.com/ht_deko/items/297c9158bece37fac7b2)


[^1]: 0 除算は考えないものとする。
[^2]: Delphi も Delphi 3 まで Real 型は 48bit だった。Delphi 4 以降、Real 型は 64bit になり、後方互換性のための Real48 型が残された。