Kagari
キーワードを入力してドキュメントを検索します。

構文

数値

数値には 2 つの系統があります。有界整数 Int<lo, hi> は、物語が実行時に保持できる唯一の数値です。チューリング完全な種別では、Rust の整数と、整数でない正確な 2 つの型 Decimal と Rat も使えます。浮動小数点数はありません。浮動小数点数は Eq ではなく(NaN != NaN)、画面は等価性で比較する必要があるからです。浮動小数点数の代わりに Decimal を、正確な分数には Rat を使います。

型値実行時に保持できる種別
Int<lo, hi>lo から hi までの整数(両端を含む)すべての種別
u8 … u128、i8 … i128、usize、isizeRust と同じfn、const fn
Decimal正確な十進数fn、const fn
Rat正確な分数fn、const fn

これらの型の定数式は、値がコンパイル時に計算されるので、pushdown fn の中にも書けます。たとえばレンダー関数の中の fade(ms(500)) です。pushdown fn にできないのは、それらを実行時に保持することです。そうした型のローカル変数、パラメータ、戻り値、物語変数はエラーになります(有限型を参照)。

Int<lo, hi>

kis
static mut AFFECTION_MIO: Int<0, 5> = 0;

Int<lo, hi> はプリミティブ型で、宣言した範囲(両端を含む)の整数です。

  • lo と hi は i64 に収まる型レベル定数で、lo <= hi でなければなりません(E2004)。
  • 既定の範囲はありません。すべての Int 型は境界を明記します。
  • アナライザは物語変数を範囲に必要なだけのビット数で表すので、0 から 5 のカウンタは 3 ビットです。収まる最小の範囲を使ってください。

パターンはリテラルと範囲で Int の値に一致し、しきい値はそのように書きます。

kis
match AFFECTION_MIO {
3..=5 => MioSmiles(),
_ => MioShrugs(),
}

整数リテラル

接尾辞のない整数リテラルは「整数 n」という柔軟な型を持ちます。文脈が期待する整数型(Int<lo, hi> または Rust の整数)の範囲が n を含む限り、その型になります。含まなければ E2013 です。何も型を決めない場合、リテラルは Int<n, n> になります。接尾辞は型を固定し、5u8 は u8 です。整数リテラルが Decimal や Rat になることはありません。1 ではなく 1.0 と書きます。

kis
let a: Int<0, 5> = 3; // Int<0, 5>
let b: u32 = 3; // u32
let c = 3u8; // u8
let d: Int<0, 5> = 9; // E2013: 9 does not fit

リテラルだけの演算はリテラルの範囲で計算されます。2 * 3 は「整数 6」です。コンパイラは整数を 128 ビットで表すので、i128::MAX を超える u128 の値はリテラルとして書けません。

Int の算術

暫定。 有界整数の算術は正確です。結果の型はとりうる結果すべての範囲なので、実行時にオーバーフローしません。

式(a: Int<l1, h1>、b: Int<l2, h2>)型
a + bInt<l1 + l2, h1 + h2>
a - bInt<l1 - h2, h1 - l2>
a * b4 つの角の積を含む最小の範囲
a / b4 つの角の商を含む最小の範囲
a % b被除数と、除数の絶対値の最大値から 1 を引いた値で抑えられる範囲
-aInt<-h1, -l1>
a == b、a < b、…bool
  • 除算は 0 方向に切り捨て、% の符号は Rust と同じく被除数に従います。
  • / と % の除数の範囲は 0 を含んではいけません(E2016)。match などで先に型を狭めてください。
  • ビット演算子 & | ^ << >> と ! は Int には定義されていません(E2015)。
  • Int と Rust の整数は 1 つの演算や比較の中で混ぜられません(E2014)。先にどちらかを変換してください。
  • 結果の範囲が 128 ビットに収まらなければ E2015 です。

拡大と複合代入

値は、自分の範囲を含む範囲の Int 型へ暗黙に変換されます。Int<1, 6> は Int<0, 10> に格納できます。より広い範囲の値を格納するには .saturate() で変換します(変換を参照)。

複合代入は飽和します。 Int の変数に対する x += e、x -= e、x *= e、x /= e、x %= e は、正確な結果を計算して x の境界に切り詰めます。x += 1 は x = (x + 1).saturate() です。右辺は任意の Int でかまいません。飽和によってすべてのステップは全域的になります。これは定義された動作で、実行時エラーにはなりません。/= と %= の除数の範囲は 0 を含んではならず、ビット演算の複合代入は Int には定義されていません。

kis
static mut AFFECTION_MIO: Int<0, 5> = 0;
pushdown fn praise() {
AFFECTION_MIO += 1; // stays 5 once it is 5
}

黙って飽和するカウンタは、範囲が狭すぎることを示していることがよくあります。

変換

リテラルと、Int 型から別の Int 型への拡大を除き、整数型が暗黙に変換されることはありません。標準ライブラリのトレイト Integer は Int<lo, hi> とすべての Rust の整数が実装しており、2 つの明示的な変換を提供します。変換先の型は文脈から推論するか、ターボフィッシュ(x.into::<u32>())で書きます。

メソッド結果
x.into()同じ値。変換元の型のすべての値が変換先の型に収まらなければコンパイルエラーです(E2018)
x.saturate()変換先の型の範囲に切り詰めた値
kis
const fn label_width(chars: Int<0, 40>) -> u32 {
let n: u32 = chars.into(); // every Int<0, 40> fits in u32
n * 16
}
fn set_level(level: u32) {
let level: Int<0, 100> = level.saturate();
MUSIC.set(volume(level));
}

as によるキャストはありません(E2019)。整数と Decimal の間の変換はありません。Rat::new は 2 つの i128 から Rat を作り、Rat::to_decimal は Rat を Decimal に変換します。

Rust の整数

チューリング完全な種別では Rust の整数型 u8、u16、u32、u64、u128、i8、i16、i32、i64、i128、usize、isize を使えます。usize と isize はどのプラットフォームでも 64 ビットです。

演算子意味
+ - * / %算術。両辺は同じ型です
& | ^ビット積、ビット和、ビット排他的論理和
<< >>シフト。シフト量の型は任意の整数型でかまいません
-x符号反転。符号付き型のみ(E2015)
!xビット否定
== != < <= > >=比較
  • 算術は検査されます。オーバーフロー、ゼロ除算、型の範囲外の結果はエラーです(エラーを参照)。黙って折り返すことはありません。
  • / は 0 方向に切り捨て、% の符号は被除数に従います。
  • シフト量は型のビット幅より小さくなければなりません。<< はあふれたビットを捨て、>> は符号付き型では算術シフトです。
  • 異なる 2 つの Rust の整数型は混ぜられません。.into() か .saturate() で変換します。

Decimal

Decimal は正確な十進数で、不透明度、音量、レイアウト上の位置など、もともと十進で書く値に使います。0.5 や 1.0 のように小数点を含むリテラルは Decimal です。浮動小数点数の代わりであり、Eq です。0.1 + 0.2 == 0.3 は true です。

演算子意味
+ - *正確
/正確に計算したうえで、小数点以下 7 桁までを 0 方向に切り捨てます。1.0 / 3.0 は 0.3333333 です
-x符号反転
== != < <= > >=比較

Decimal に % はありません。Decimal の仮数部は 128 ビットで、収まらない結果はオーバーフローエラーです。

Rat

Rat は正確な有理数で、既約の分子と正の分母(どちらも i128)からなります。Rat のリテラルはありません。値は Rat::new(num, den) と書き、分数は約分されます(Rat::new(2, -4) は -1/2)。den == 0 はゼロ除算です。

演算子は Decimal と同じで、/ は正確です。Rat::to_decimal は Decimal に変換します。整数部と小数点以下最大 7 桁を残し、0 方向に切り捨てます(Rat::new(1, 3).to_decimal() は 0.3333333、Rat::new(-2, 3).to_decimal() は -0.6666666)。

kis
const fn rats() -> Rat {
let a = Rat::new(1, 3);
a * a - a / Rat::new(2, 1) // 1/9 - 1/6 = -1/18
}

コンパイル時と実行時のエラー

エラーコンパイル時の評価中実行時
オーバーフロー、型の範囲外の結果、不正なシフト量E4001VM パニック
ゼロ除算、Rat::new(_, 0)E4002VM パニック

VM パニックは定義されたゲームの停止で、ランタイムが扱います。コンパイル時に評価されるコード(定数、レンダー関数、物語から呼ばれる const fn)では、これらのエラーは値を必要とした呼び出しの位置で診断として報告されるので、物語そのものがこの形で失敗することはありません。Int<lo, hi> の複合代入は飽和し、失敗しません。

最終更新日 2026年10月29日