本文へ移動
Hikari 仕様

std:math — 数学関数

標準ライブラリモジュール (index.md)。本書中の裸の §N は本書の節を指す。言語の意味論は ../language-spec.md を参照。

import math := "std:math" は定数 pi / e と、abs / sign / sqrt / cbrt / exp / log / log2 / log10 / sin / cos / tan / asin / acos / atan / atan2 / floor / ceil / round / trunc の関数を持つ namespace object を math に束縛する。実数計算(割合・統計・幾何・科学計算)を担う。累乗は演算子 **../language-spec.md §8)を使う。

std:fs / std:term と違い I/O を伴わず、純粋・同期 (Future を返さない)。std:path / std:json と同じく、すべて与えられた数値だけを見て値を直接返す。

import math := "std:math"

math.sqrt(2.0)        #> 1.4142135623730951
2.0 ** 10.0           #> 1024.0
math.abs(-5)          #> 5
math.pi               #> 3.141592653589793
名前 意味
pi 定数 円周率 π (Float)
e 定数 自然対数の底 e (Float)
abs abs(x) x の絶対値。x と同じ数値型を返す
sign sign(x) 符号 (負 -1・零 0・正 1)。x と同じ数値型を返す
sqrt sqrt(x) 平方根 (Float)。x < 0.0NaN
cbrt cbrt(x) 立方根 (Float)。負も定義され実数根を返す
exp exp(x) ex 乗 (Float)
log log(x) 自然対数 (Float)。x < 0.0NaNx == 0.0-Inf
log2 log2(x) 底 2 の対数 (Float)
log10 log10(x) 底 10 の対数 (Float)
sin cos tan sin(x) 三角関数 (Float)。x はラジアン
asin acos atan asin(x) 逆三角関数 (Float)。結果はラジアン。定義域外は NaN
atan2 atan2(y, x) y/x の逆正接 (Float)。象限を考慮しラジアンを返す
floor ceil round trunc floor(x) x を整数値へ丸めた Float

本モジュールは効果を1 つも持たない../language-spec.md §17.9)。

以下の例では import math := "std:math" で束縛したものとして math.sqrt 等で記す。全関数は値を 直接返す (Future でも Result/Option でもない)。

1. 数値型ポリシー — Float 専用と数値多相

Hikari は IntFloat暗黙に変換しない../language-spec.md §7.1)。本モジュールはこの厳格規律に従い、関数を 2 層に分ける。

  • Float 専用: sqrt / cbrt / exp / log / log2 / log10 / sin / cos / tan / asin / acos / atan / atan2 / floor / ceil / round / trunc。引数は すべて FloatInt を渡すと呼び出し位置で Error (§6)。Int から計算するときは x.to_float! で明示変換する (Int.to_float は全域関数。リテラルなら 2.0 と直接書く)。
math.sqrt 2.0   #> 1.4142135623730951
math.sqrt 2     # error: Int は不可 (§6 の型エラー)
math.sqrt (2.to_float!)  #> 1.4142135623730951   (Int から計算するときの綴り)
  • 数値多相 (a: Number): abs / sign。シグネチャは境界付き型変数(../language-spec.md §17.2)で書く — abs: {(a: Number) | a}Int でも Float でも動き、入力と同じ型を返す(演算子の型ディスパッチと一貫)。いずれも単項なので引数間の型混在は起きない。
math.abs (-5)  #> 5      (Int → Int)
math.abs (-5.0)  #> 5.0    (Float → Float)
math.sign (-3)  #> -1

2. 定数

  • pi — 円周率 π を最も近い Float で表した値 (3.141592653589793)
  • e — 自然対数の底 e を最も近い Float で表した値 (2.718281828459045)

定数は関数ではなく値スロットで、呼び出さずに参照する (math.pi)。

3. abs / sign

  • abs(x)x の絶対値を x と同じ型で返す。Int / Float のみ受け付け、他型は §6 のエラー
    • FloatabsNaNNaN±Inf+Inf にする (math.Abs 相当)
    • Intabs はオーバーフローしない(任意精度のため「最小の Int」のような端点はなく、常に正確な絶対値を正値で返す。Int の演算と一貫、language-spec.md §7.1
  • sign(x) — 符号を x と同じ型で返す。負なら -1、零なら 0、正なら 1 (Float なら -1.0 / 0.0 / 1.0)
    • Floatsign: NaNNaN±0.00.0±Inf±1.0
math.abs (-5)  #> 5
math.abs 5.0  #> 5.0
math.sign (-3)  #> -1
math.sign 0  #> 0
math.sign 2.5  #> 1.0

abs の内部比較は 全順序language-spec.md §9compare と同じ順序)で行う。したがって FloatNaN にも定位置があり (-NaN が最小・+NaN が最大)、-0.0 < +0.0 を区別する。sort / compare と矛盾しない。

4. 冪根・指数・対数・三角関数

すべて Float 専用§1)。定義域外は IEEE 754 に従って NaN / ±Inf を返す(§6 の「定義域外」)。

  • sqrt(x) — 平方根。x < 0.0NaN
  • cbrt(x) — 立方根。負の x でも実数の立方根を返す (cbrt(-8.0) #> -2.0)
  • exp(x)e ** x
  • log(x) — 自然対数 (底 e)。x < 0.0NaNx == 0.0-Inf
  • log2(x) / log10(x) — 底 2 / 底 10 の対数
  • sin(x) / cos(x) / tan(x) — 三角関数。x はラジアン
  • asin(x) / acos(x) / atan(x) — 逆三角関数。結果はラジアン。asin / acos|x| > 1.0NaN
  • atan2(y, x)(x, y) の偏角をラジアン (-pi..pi) で返す。象限を正しく扱う
math.sqrt 2.0  #> 1.4142135623730951
2.0 ** 10.0  #> 1024.0
math.log math.e  #> 1.0
math.sin 0.0  #> 0.0
math.atan2(1.0, 1.0)  #> 0.7853981633974483   (pi/4)

5. 丸め関数

floor / ceil / round / truncFloat 専用で、整数値の Float を返す。Float 型には同名のメソッド (x.floor 等、prelude.md) もあり、本モジュールは関数形を提供する(map(math.floor, xs) のような関数合成・高階利用のため)。両者は同値。

  • floor(x)x 以下の最大の整数値 (floor(2.7) #> 2.0floor(-2.1) #> -3.0)
  • ceil(x)x 以上の最小の整数値 (ceil(2.1) #> 3.0)
  • round(x) — 最も近い整数値。半数はゼロから遠い方へ丸める (round(2.5) #> 3.0round(-2.5) #> -3.0)
  • trunc(x) — 小数部を捨てる (ゼロ方向、trunc(2.7) #> 2.0trunc(-2.7) #> -2.0)

NaN / ±Inf はそのまま返す。

6. エラーモデル

std:math2 種の結果を使い分ける。

  1. 値を直接返す(成功・定義域外とも): 大半の関数。引数の型さえ合えば値を返す。定義域外sqrt(-1.0)log(0.0)asin(2.0) など)は回復可能エラーではなく IEEE 754 の NaN / ±Inf を返す。これは Floatsqrt メソッド(prelude.md、math.Sqrt 直呼び)と一貫する。FloatNaN / Inf を通常の値として許容し全順序で比較できる数値モデル(../language-spec.md §7.1・§9)を採るため、定義域外だけを Option 化すると整合が崩れる。残った非有限値は全順序(§3)が安全網となり sort / data 構造を壊さない
  1. Error(バグ層、language-spec.md §16: 型が合わない呼び出し。回復可能エラーではなく呼び出し位置で停止する。json.md §5・path.md §10 の引数型エラーと同じ規律:
    • Float 専用関数に Int その他を渡す
    • 数値多相関数 (abs / sign) に非数値を渡す

定義域外(1)と型エラー(2)は層が異なる: 前者は「型は正しいが数学的に範囲外」で IEEE 値を返し続行可能、後者は「そもそも型が違う」呼び出し側のバグなので停止する。