# 機能設計書 52-fenv（浮動小数点環境）

## 概要

本ドキュメントは、Nim標準ライブラリの浮動小数点環境制御モジュール（fenv.nim）について、その設計と仕様を詳細に記載した機能設計書である。

### 本機能の処理概要

fenvモジュールは、浮動小数点の丸めモードと例外（オーバーフロー、ゼロ除算など）の制御を提供する。型、変数、プロシージャはC標準ライブラリの`<fenv.h>`ヘッダへのバインディングである。

**業務上の目的・背景**：数値計算や科学計算において、浮動小数点演算の丸めモードの制御や例外処理は精度と信頼性の確保に不可欠である。本モジュールにより、プログラマーは浮動小数点演算の動作を細かく制御でき、IEEE 754準拠の演算結果を得ることができる。

**機能の利用シーン**：
- 金融計算における特定の丸めモード（例：切り捨て、切り上げ）の適用
- 数値シミュレーションでのオーバーフロー/アンダーフローの検出
- 科学計算でのゼロ除算例外の監視
- 浮動小数点型の精度情報（仮数部のビット数、最大/最小値など）の取得

**主要な処理内容**：
1. 浮動小数点例外フラグのクリア・テスト・発生（feclearexcept, fetestexcept, feraiseexcept）
2. 丸めモードの取得・設定（fegetround, fesetround）
3. 浮動小数点環境全体の保存・復元（fegetenv, fesetenv, feholdexcept, feupdateenv）
4. 浮動小数点型の特性定数の提供（FLT_*/DBL_*定数、epsilon, minimumPositiveValue等のテンプレート）

**関連システム・外部連携**：C標準ライブラリの`<fenv.h>`に依存する。POSIXシステムでは`-lm`（数学ライブラリ）をリンクする。

**権限による制御**：特になし。すべての機能が任意のコードから利用可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 本モジュールはライブラリ機能であり、直接の画面関連なし |

## 機能種別

計算処理 / システム制御

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|-----------------|
| excepts | cint | Yes | 例外フラグのビットマスク（FE_DIVBYZERO, FE_INVALID等の組み合わせ） | 有効な例外フラグの組み合わせ |
| roundingDirection | cint | Yes | 丸めモード（FE_TONEAREST, FE_DOWNWARD, FE_UPWARD, FE_TOWARDZERO） | 有効な丸めモード値 |
| envp | ptr Tfenv | Yes | 浮動小数点環境を保存/復元するためのポインタ | 有効なメモリアドレス |
| flagp | ptr Tfexcept | Yes | 例外フラグを保存/復元するためのポインタ | 有効なメモリアドレス |

### 入力データソース

- プログラムから直接指定される定数値
- システムの現在の浮動小数点環境

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 丸めモード | cint | 現在の丸め方向 |
| 例外フラグ | cint | 現在設定されている例外のビットマスク |
| 浮動小数点環境 | Tfenv | 完全な浮動小数点環境状態 |
| float32特性 | 各種 | 32ビット浮動小数点の特性（epsilon, min, max等） |
| float64特性 | 各種 | 64ビット浮動小数点の特性（epsilon, min, max等） |

### 出力先

呼び出し元への戻り値、または指定されたポインタへの書き込み

## 処理フロー

### 処理シーケンス

```
1. 例外処理フロー
   └─ feclearexcept(excepts): 指定した例外フラグをクリア
   └─ feraiseexcept(excepts): 指定した例外を発生させる
   └─ fetestexcept(excepts): 指定した例外がセットされているかテスト

2. 丸めモード制御フロー
   └─ fegetround(): 現在の丸めモードを取得
   └─ fesetround(mode): 丸めモードを設定

3. 環境保存・復元フロー
   └─ fegetenv(envp): 現在の環境を保存
   └─ fesetenv(envp): 保存した環境を復元
   └─ feholdexcept(envp): 環境を保存し、例外をクリアしてnon-stopモードに
   └─ feupdateenv(envp): 現在の例外を保存、環境を復元、保存した例外を発生
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{操作種別}
    B -->|例外制御| C[feclearexcept/feraiseexcept/fetestexcept]
    B -->|丸めモード| D[fegetround/fesetround]
    B -->|環境保存| E[fegetenv/feholdexcept]
    B -->|環境復元| F[fesetenv/feupdateenv]
    C --> G[C標準ライブラリ呼び出し]
    D --> G
    E --> G
    F --> G
    G --> H[結果返却]
    H --> I[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | C標準準拠 | すべての関数はC標準ライブラリの<fenv.h>に準拠 | 常に適用 |
| BR-002 | 例外ビットマスク | FE_ALL_EXCEPT はすべての例外フラグのビットOR | 常に適用 |
| BR-003 | 丸めモード排他 | 丸めモードは同時に1つのみ有効 | fesetroundの呼び出し時 |
| BR-004 | POSIXリンク | POSIX環境では-lmリンクが必要 | POSIXかつmacOS以外 |

### 計算ロジック

**浮動小数点定数**:
- `FLT_RADIX = 2`: 指数表現の基数
- `FLT_MANT_DIG = 24`: float32の仮数部ビット数
- `DBL_MANT_DIG = 53`: float64の仮数部ビット数
- `FLT_EPSILON = 1.19209290e-07`: float32の機械イプシロン
- `DBL_EPSILON = 2.2204460492503131E-16`: float64の機械イプシロン

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

### 操作別データベース影響一覧

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 非ゼロ戻り値 | 操作失敗 | 各fenv関数が非ゼロを返した場合 | 戻り値を確認し、エラー処理を行う |
| 未定義動作 | サポート外 | 未サポートの丸めモードや例外を指定した場合 | プラットフォームのサポート状況を確認 |

### リトライ仕様

リトライ不要（システム呼び出しのため）

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

データベース操作がないため該当なし

## パフォーマンス要件

- すべての関数はC標準ライブラリへの直接呼び出しであり、オーバーヘッドは最小限
- テンプレートによる定数取得はコンパイル時に解決される

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

- ポインタを受け取る関数では有効なメモリアドレスを渡す必要がある
- 浮動小数点環境の変更はプロセス全体に影響するため、スレッド安全性に注意

## 備考

- 本モジュールはC言語の`<fenv.h>`へのバインディングである
- macOS以外のPOSIX環境では`-lm`リンクが自動的に行われる

---

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

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

### 推奨読解順序

#### Step 1: データ構造を理解する

まず、浮動小数点環境を表す型定義を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | fenv.nim | `lib/pure/fenv.nim` | Tfenv型とTfexcept型の定義（44-59行目） |

**読解のコツ**: Tfenv は浮動小数点環境全体、Tfexcept は例外フラグの集合を表す。いずれもC言語の構造体への直接マッピング。

#### Step 2: 例外フラグ変数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | fenv.nim | `lib/pure/fenv.nim` | FE_DIVBYZERO等の例外フラグ変数（18-30行目） |

**主要変数**:
- **19行目**: FE_DIVBYZERO - ゼロ除算
- **21行目**: FE_INEXACT - 不正確な結果
- **23行目**: FE_INVALID - 無効な操作
- **25行目**: FE_OVERFLOW - オーバーフロー
- **27行目**: FE_UNDERFLOW - アンダーフロー
- **29行目**: FE_ALL_EXCEPT - 全例外のOR

#### Step 3: 丸めモード変数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | fenv.nim | `lib/pure/fenv.nim` | FE_DOWNWARD等の丸めモード変数（31-39行目） |

**主要変数**:
- **31行目**: FE_DOWNWARD - 負の無限大方向に丸め
- **33行目**: FE_TONEAREST - 最近接偶数への丸め
- **35行目**: FE_TOWARDZERO - ゼロ方向に丸め
- **37行目**: FE_UPWARD - 正の無限大方向に丸め

#### Step 4: 例外制御プロシージャを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | fenv.nim | `lib/pure/fenv.nim` | feclearexcept, feraiseexcept, fetestexcept（61-79行目） |

#### Step 5: 丸めモード制御を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | fenv.nim | `lib/pure/fenv.nim` | fegetround, fesetround（81-85行目） |

#### Step 6: 環境保存・復元を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 6-1 | fenv.nim | `lib/pure/fenv.nim` | fegetenv, feholdexcept, fesetenv, feupdateenv（87-103行目） |

#### Step 7: 浮動小数点特性定数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 7-1 | fenv.nim | `lib/pure/fenv.nim` | FLT_*, DBL_*定数（105-127行目） |
| 7-2 | fenv.nim | `lib/pure/fenv.nim` | float32/float64用テンプレート（128-183行目） |

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

```
ユーザーコード
    │
    ├─ 例外制御
    │      ├─ feclearexcept(excepts) ─────▶ C: feclearexcept
    │      ├─ feraiseexcept(excepts) ─────▶ C: feraiseexcept
    │      ├─ fetestexcept(excepts) ──────▶ C: fetestexcept
    │      ├─ fegetexceptflag(flagp, excepts) ▶ C: fegetexceptflag
    │      └─ fesetexceptflag(flagp, excepts) ▶ C: fesetexceptflag
    │
    ├─ 丸めモード制御
    │      ├─ fegetround() ───────────────▶ C: fegetround
    │      └─ fesetround(mode) ───────────▶ C: fesetround
    │
    ├─ 環境制御
    │      ├─ fegetenv(envp) ─────────────▶ C: fegetenv
    │      ├─ fesetenv(envp) ─────────────▶ C: fesetenv
    │      ├─ feholdexcept(envp) ─────────▶ C: feholdexcept
    │      └─ feupdateenv(envp) ──────────▶ C: feupdateenv
    │
    └─ 特性テンプレート（コンパイル時解決）
           ├─ epsilon(float32/float64) ───▶ FLT_EPSILON/DBL_EPSILON
           ├─ minimumPositiveValue ───────▶ FLT_MIN/DBL_MIN
           └─ maximumPositiveValue ───────▶ FLT_MAX/DBL_MAX
```

### データフロー図

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

例外マスク ───────▶ feclearexcept() ─────────▶ 例外クリア（副作用）
例外マスク ───────▶ feraiseexcept() ─────────▶ 例外発生（副作用）
例外マスク ───────▶ fetestexcept() ──────────▶ 例外状態(cint)

なし ─────────────▶ fegetround() ────────────▶ 丸めモード(cint)
丸めモード ───────▶ fesetround() ────────────▶ 設定結果(cint)

envpポインタ ─────▶ fegetenv() ──────────────▶ 環境保存（副作用）
envpポインタ ─────▶ fesetenv() ──────────────▶ 環境復元（副作用）

型指定 ───────────▶ epsilon(T) ──────────────▶ 機械イプシロン(T)
型指定 ───────────▶ minimumPositiveValue(T) ─▶ 最小正値(T)
型指定 ───────────▶ maximumPositiveValue(T) ─▶ 最大正値(T)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| fenv.nim | `lib/pure/fenv.nim` | ソース | 浮動小数点環境制御の主要実装 |
| fenv.h | システム標準 | ヘッダ | C標準ライブラリの浮動小数点環境ヘッダ |
