# 機能設計書 28-基本演算

## 概要

本ドキュメントは、Nushellにおける基本演算機能の設計仕様を記述する。

### 本機能の処理概要

基本演算機能は、数値に対する基本的な数学関数を提供する。絶対値、切り上げ、切り捨て、四捨五入、平方根、対数などの演算により、データの変換や計算処理を行う。

**業務上の目的・背景**：数値データの処理において、基本的な数学演算は不可欠である。統計処理、データ正規化、スケーリング、表示整形など、様々な場面で数学関数が必要となる。これらの関数をパイプライン内で直接使用できることで、データ処理ワークフローの効率化を実現する。

**機能の利用シーン**：
- 数値データの絶対値を取得する場合
- 小数点以下を切り捨て/切り上げする場合
- 表示用に数値を四捨五入する場合
- 対数スケールでの計算を行う場合

**主要な処理内容**：
1. `math abs` - 絶対値の計算
2. `math ceil` - 切り上げ（天井関数）
3. `math floor` - 切り捨て（床関数）
4. `math round` - 四捨五入
5. `math sqrt` - 平方根
6. `math log` - 対数

**関連システム・外部連携**：特になし。Nushell内部の数学処理として動作する。

**権限による制御**：特になし。すべてのユーザーが使用可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | メインREPL | 結果表示画面 | コマンド実行結果の表示 |

## 機能種別

計算処理 / 数学関数

## 入力仕様

### 入力パラメータ

#### math abs

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| なし | - | - | パイプラインから数値を受け取る | - |

#### math ceil / floor

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| なし | - | - | パイプラインから数値を受け取る | - |

#### math round

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| --precision / -p | Int | No | 小数点以下の桁数 | - |

#### math log

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| base | Number | Yes | 対数の底 | 正の数 |

### 入力データソース

パイプライン入力（数値、リスト、Range）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| result (abs) | Number | 絶対値（入力型と同じ） |
| result (ceil/floor) | Int | 整数値 |
| result (round) | Number | 四捨五入された値 |
| result (sqrt/log) | Float | 計算結果 |

### 出力先

パイプライン出力

## 処理フロー

### 処理シーケンス

```
1. パイプラインから入力値を受け取る
   └─ 数値、リスト、Rangeを受け付ける
2. 入力型を確認
   └─ Range: 有界範囲かチェック
3. 各要素に対して演算を実行
4. 結果を出力する
```

### フローチャート

```mermaid
flowchart TD
    A[入力受信] --> B{入力型}
    B -->|Number| C[演算実行]
    B -->|List| D[各要素に演算適用]
    B -->|Range| E{有界範囲?}
    E -->|Yes| F[展開して処理]
    E -->|No| G[エラー]
    C --> H[結果出力]
    D --> H
    F --> H
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-28-1 | Duration対応 | absはDuration型もサポート | math abs使用時 |
| BR-28-2 | 精度指定 | roundは--precisionで桁数指定可能 | math round使用時 |
| BR-28-3 | 負の精度 | roundは負の精度で10の位以上で丸め可能 | math round使用時 |
| BR-28-4 | 有界範囲要求 | Range入力は有界でなければエラー | 常時 |

### 計算ロジック

math round の精度計算：
- precision > 0: 小数点以下precision桁で四捨五入
- precision = 0: 整数に四捨五入
- precision < 0: 10^|precision|の位で四捨五入

計算式: `(val * 10^precision).round() / 10^precision`

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

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| OnlySupportsThisInputType | 型エラー | 数値以外の入力 | 数値を入力する |
| UnsupportedInput | 非有限値 | 無限大やNaNのround | 有限値を入力する |
| PipelineEmpty | 空入力 | 入力がない場合 | データを入力する |

### リトライ仕様

該当なし

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

該当なし（ステートレス処理）

## パフォーマンス要件

- Rustの標準数学関数を使用した高速な処理
- リスト入力時は各要素に対してmap処理を適用

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

特になし

## 備考

- すべてのmath基本演算コマンドは定数式として評価可能（is_const = true）
- 整数入力に対するceil/floorはそのまま値を返す

---

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

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

### 推奨読解順序

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

mathモジュールの構成を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | mod.rs | `crates/nu-command/src/math/mod.rs` | モジュール構成（1-37行目） |
| 1-2 | utils.rs | `crates/nu-command/src/math/utils.rs` | 共通ユーティリティ関数 |

**読解のコツ**: mathモジュールは各演算ごとに独立したファイルで実装。utils.rsにensure_bounded等の共通関数がある。

#### Step 2: エントリーポイントを理解する

コマンド実行の起点を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | abs.rs | `crates/nu-command/src/math/abs.rs` | `impl Command for MathAbs`（7-89行目） |
| 2-2 | round.rs | `crates/nu-command/src/math/round.rs` | `impl Command for MathRound`（7-125行目） |

**主要処理フロー**:
1. **abs.rs 43-56行目**: `run`メソッドでRange有界チェックとmap処理
2. **round.rs 44-65行目**: `run`メソッドで精度取得とmap処理

#### Step 3: 演算ロジックを理解する

実際の数学演算を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | abs.rs | `crates/nu-command/src/math/abs.rs` | abs_helper関数（91-108行目）- 絶対値計算 |
| 3-2 | ceil.rs | `crates/nu-command/src/math/ceil.rs` | operate関数（90-106行目）- 切り上げ |
| 3-3 | floor.rs | `crates/nu-command/src/math/floor.rs` | operate関数（90-106行目）- 切り捨て |
| 3-4 | round.rs | `crates/nu-command/src/math/round.rs` | operate関数（127-170行目）- 四捨五入 |

**主要処理フロー**:
- **abs.rs 94行目**: `val.abs()` で絶対値計算
- **ceil.rs 94行目**: `val.ceil() as i64` で切り上げ
- **floor.rs 94行目**: `val.floor() as i64` で切り捨て
- **round.rs 151-156行目**: 精度付き四捨五入の計算式

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

```
MathAbs::run / MathCeil::run / MathFloor::run / MathRound::run
    │
    ├─ ensure_bounded() (Range入力時)
    │      └─ 有界範囲チェック
    │
    └─ input.map()
           │
           └─ abs_helper() / operate()
                  │
                  ├─ Value::Int → .abs() / そのまま / 計算
                  ├─ Value::Float → .abs() / .ceil() / .floor() / .round()
                  └─ Value::Duration → .abs() (absのみ)
```

### データフロー図

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

Number ───▶ math abs ───▶ .abs() ───▶ Number
   │              │
   │              └─ Int/Float/Duration対応
   │
Float ───▶ math ceil ───▶ .ceil() as i64 ───▶ Int
   │
Float ───▶ math floor ───▶ .floor() as i64 ───▶ Int
   │
Float ───▶ math round ───▶ (val * 10^p).round() / 10^p ───▶ Number
   │              │
   │              └─ --precision で桁数指定
   │
List<Number> ───▶ math * ───▶ 各要素に適用 ───▶ List<Number>
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| abs.rs | `crates/nu-command/src/math/abs.rs` | ソース | math abs コマンド実装 |
| ceil.rs | `crates/nu-command/src/math/ceil.rs` | ソース | math ceil コマンド実装 |
| floor.rs | `crates/nu-command/src/math/floor.rs` | ソース | math floor コマンド実装 |
| round.rs | `crates/nu-command/src/math/round.rs` | ソース | math round コマンド実装 |
| sqrt.rs | `crates/nu-command/src/math/sqrt.rs` | ソース | math sqrt コマンド実装 |
| log.rs | `crates/nu-command/src/math/log.rs` | ソース | math log コマンド実装 |
| utils.rs | `crates/nu-command/src/math/utils.rs` | ソース | 共通ユーティリティ |
| mod.rs | `crates/nu-command/src/math/mod.rs` | ソース | mathモジュール定義 |
