# 機能設計書 108-jsbigints

## 概要

本ドキュメントは、Nim標準ライブラリの`jsbigints`モジュールの機能設計を記述する。このモジュールは、JavaScriptバックエンド向けに任意精度整数（BigInt）のサポートを提供する。

### 本機能の処理概要

`jsbigints`モジュールは、JavaScriptのBigInt APIをNimから利用するためのラッパーを提供する。通常の整数型では表現できない大きな数値を扱うことができ、暗号計算や金融計算など、高精度が必要な場面で使用される。

**業務上の目的・背景**：Web開発において、64ビット整数を超える大きな数値を扱う必要がある場面（暗号通貨、大規模ID、高精度計算など）では、JavaScriptのBigIntが必要となる。本モジュールにより、NimのJavaScriptバックエンドでもBigIntをネイティブに利用できる。

**機能の利用シーン**：暗号計算、大規模システムのID生成、金融計算での高精度演算、科学計算など。

**主要な処理内容**：
1. BigIntの作成（整数、文字列から）
2. 算術演算（加算、減算、乗算、除算、剰余）
3. ビット演算（AND、OR、XOR、シフト）
4. 比較演算
5. 文字列変換（任意の基数）

**関連システム・外部連携**：JavaScript BigInt API。

**権限による制御**：権限による制御は存在しない。

## 関連画面

本モジュールは標準ライブラリであり、特定の画面との関連はない。

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | - |

## 機能種別

数値演算 / JavaScript連携

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| integer | SomeInteger | Yes | BigIntに変換する整数 | Nimの整数型 |
| num | cstring | Yes | BigIntに変換する数値文字列 | 有効な数値形式 |
| radix | 2..36 | No | 文字列変換時の基数 | 2以上36以下 |
| bits | Natural | Yes | ビット数（wrapTo系） | 0以上 |

### 入力データソース

プログラムコードからの直接呼び出し。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| JsBigInt | distinct type | 任意精度整数 |
| cstring | cstring | 文字列表現 |
| string | string | Nim文字列表現（"n"サフィックス付き） |
| int | int | 通常整数への変換（精度低下の可能性） |
| bool | bool | 比較結果 |

### 出力先

呼び出し元への戻り値。

## 処理フロー

### 処理シーケンス

```
1. BigInt作成
   └─ big(integer): 整数からBigInt作成
   └─ big(cstring): 文字列からBigInt作成
   └─ 'big リテラル: 数値リテラルから作成

2. 算術演算
   └─ 各演算はJavaScriptのBigInt演算に直接マッピング

3. 文字列変換
   └─ toCstring: 指定基数で文字列化
   └─ $: "n"サフィックス付き文字列

4. ビットラップ
   └─ wrapToInt: 符号付きでビット数に丸め
   └─ wrapToUint: 符号なしでビット数に丸め
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{入力タイプ?}
    B -->|整数| C[big(integer)]
    B -->|文字列| D[big(cstring)]
    B -->|リテラル| E['big リテラル]
    C --> F[JsBigInt]
    D --> F
    E --> F

    G[演算] --> H{演算種類?}
    H -->|算術| I[+ - * div mod]
    H -->|比較| J[< <= == > >=]
    H -->|ビット| K[and or xor shl shr]
    I --> L[JsBigInt結果]
    J --> M[bool結果]
    K --> L
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | JSバックエンド限定 | JavaScriptバックエンドでのみ使用可能 | コンパイル時 |
| BR-02 | コンパイル時使用不可 | static/const式内では使用不可 | コンパイル時 |
| BR-03 | 負の指数不可 | `**`演算子で負の指数はRangeError | 実行時 |
| BR-04 | 単項プラス不可 | `+`単項演算子は使用禁止（asm.js互換性） | コンパイル時 |

### 計算ロジック

**文字列変換**:
```nim
func `$`*(this: JsBigInt): string =
  $toCstring(this) & 'n'  # "1234n"形式
```

**ビットラップ（符号付き）**:
```nim
# wrapToInt: -2^(bits-1) から 2^(bits-1)-1 の範囲に丸め
BigInt.asIntN(bits, value)
```

**ビットラップ（符号なし）**:
```nim
# wrapToUint: 0 から 2^bits-1 の範囲に丸め
BigInt.asUintN(bits, value)
```

## データベース操作仕様

本モジュールはデータベース操作を行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| コンパイルエラー | ビルドエラー | JSバックエンド以外で使用 | JSバックエンドでコンパイル |
| RangeError | JavaScript例外 | 負の指数で累乗 | 正の指数を使用 |

### リトライ仕様

リトライは不要。

## トランザクション仕様

トランザクション管理は不要。

## パフォーマンス要件

- JavaScriptエンジンのBigInt実装に依存
- ネイティブBigInt操作のため高速

## セキュリティ考慮事項

- toNumber関数は精度が失われる可能性があるため、大きな値の変換に注意

## 備考

- JSバックエンド専用モジュール
- low/high関数は使用不可（任意精度のため）
- MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: 型定義とプラットフォーム制限を理解する

JsBigInt型の定義とJSバックエンド制限を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | jsbigints.nim | `lib/std/jsbigints.nim` | 3-4行目: JSバックエンド制限 |
| 1-2 | jsbigints.nim | `lib/std/jsbigints.nim` | 9-10行目: JsBigInt型定義 |

**読解のコツ**: `distinct`型として定義されており、内部的にはJavaScriptのBigIntにマッピングされる。`importjs: "bigint"`プラグマにより、JavaScriptとの連携が実現されている。

#### Step 2: コンストラクタを理解する

BigIntの作成方法を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | jsbigints.nim | `lib/std/jsbigints.nim` | 12-17行目: big(SomeInteger) |
| 2-2 | jsbigints.nim | `lib/std/jsbigints.nim` | 19-31行目: `'big`リテラル |
| 2-3 | jsbigints.nim | `lib/std/jsbigints.nim` | 33-35行目: big(cstring) |

**主要処理フロー**:
- **12行目**: `importjs: "BigInt(#)"`でJavaScript BigInt()を呼び出し
- **17行目**: コンパイル時使用時はraiseAssert
- **19行目**: `'big`カスタムリテラルで便利な構文を提供

#### Step 3: 文字列変換を理解する

BigIntと文字列の相互変換を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | jsbigints.nim | `lib/std/jsbigints.nim` | 37-46行目: toCstring関数 |
| 3-2 | jsbigints.nim | `lib/std/jsbigints.nim` | 48-51行目: `$`演算子 |

**主要処理フロー**:
- **37行目**: toString(radix)でJavaScriptメソッドを呼び出し
- **51行目**: `$`は"n"サフィックスを付加

#### Step 4: 算術演算を理解する

基本的な算術演算の実装を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | jsbigints.nim | `lib/std/jsbigints.nim` | 72-98行目: 算術演算子 |
| 4-2 | jsbigints.nim | `lib/std/jsbigints.nim` | 112-122行目: 累乗演算子 |

**主要処理フロー**:
- **72行目**: `+`は`importjs: "(# $1 #)"`でインライン展開
- **84-90行目**: `div`は`/`にマッピング（JavaScriptでは`/`が整数除算）
- **112行目**: `**`は`((#) $1 #)`でマイナス対応

#### Step 5: ビット演算と変換を理解する

ビット演算とwrap関数を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | jsbigints.nim | `lib/std/jsbigints.nim` | 53-65行目: wrapToInt/wrapToUint |
| 5-2 | jsbigints.nim | `lib/std/jsbigints.nim` | 67-70行目: toNumber |
| 5-3 | jsbigints.nim | `lib/std/jsbigints.nim` | 124-142行目: ビット演算子 |

**主要処理フロー**:
- **53行目**: wrapToIntはBigInt.asIntNを使用
- **60行目**: wrapToUintはBigInt.asUintNを使用
- **124行目**: `and`は`&`にマッピング

### プログラム呼び出し階層図

```
jsbigints.nim
    │
    ├─ 型定義
    │      └─ JsBigInt (distinct JsBigIntImpl)
    │
    ├─ コンストラクタ
    │      ├─ big(SomeInteger) ─── BigInt()
    │      ├─ big(cstring) ─── BigInt()
    │      └─ 'big リテラル ─── BigInt()
    │
    ├─ 文字列変換
    │      ├─ toCstring(radix) ─── toString(radix)
    │      ├─ toCstring() ─── toString()
    │      └─ `$` ─── toCstring + 'n'
    │
    ├─ 数値変換
    │      ├─ toNumber ─── Number()
    │      ├─ wrapToInt ─── BigInt.asIntN()
    │      └─ wrapToUint ─── BigInt.asUintN()
    │
    ├─ 算術演算
    │      ├─ `+` ─── JS: +
    │      ├─ `-` ─── JS: -
    │      ├─ `*` ─── JS: *
    │      ├─ `div` ─── JS: /
    │      ├─ `mod` ─── JS: %
    │      └─ `**` ─── JS: **
    │
    ├─ 比較演算
    │      ├─ `<` `<=` `==` `>` `>=`
    │      └─ JS同等演算子にマッピング
    │
    └─ ビット演算
           ├─ `and` ─── JS: &
           ├─ `or` ─── JS: |
           ├─ `xor` ─── JS: ^
           ├─ `shl` ─── JS: <<
           └─ `shr` ─── JS: >>
```

### データフロー図

```
[入力]                    [処理]                      [出力]

整数/文字列 ───────────▶ big() ─────────────────────▶ JsBigInt
                              │
                              └─▶ JavaScript: BigInt()

JsBigInt ──────────────▶ 算術演算 ──────────────────▶ JsBigInt
                              │
                              └─▶ JavaScript演算子

JsBigInt ──────────────▶ toCstring ─────────────────▶ cstring
                              │
                              └─▶ JavaScript: toString()

JsBigInt ──────────────▶ `$` ───────────────────────▶ string ("n"付き)

JsBigInt ──────────────▶ toNumber ──────────────────▶ int
                              │
                              └─▶ JavaScript: Number()（精度低下可能性）
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| jsbigints.nim | `lib/std/jsbigints.nim` | ソース | メインモジュール、全機能の実装 |
| assertions.nim | `lib/std/assertions.nim` | 依存 | assert関数 |
