# 科学计算器功能扩展设计 **日期**: 2026-07-28 **状态**: 待实现 **范围**: 桌面端 CalculatorDesktop 组件(移动端 CalculatorMobile 保持不变) --- ## 1. 背景 当前计算器仅支持基础四则运算和简单的 ±、%、√ 功能。用户希望扩展为完整的科学计算器,参考主流科学计算器(Windows 计算器 / Calculator.net / Casio fx-991)的标准功能集。 ## 2. 设计原则 - **桌面端优先**:科学函数仅修改 CalculatorDesktop,CalculatorMobile 保持现有基础布局 - **功能完整**:覆盖三角/反三角/对数/幂/根/阶乘/记忆等完整科学计算功能 - **模式切换**:顶部有基础/科学模式切换,保持原有 4 列布局宽度不变 - **错误安全**:所有数学错误友好显示 "Error",不崩溃 ## 3. 功能规格 ### 3.1 三角函数 | 按键 | 函数 | 说明 | |------|------|------| | sin | sin(x) | 正弦,支持DEG/RAD模式 | | cos | cos(x) | 余弦,支持DEG/RAD模式 | | tan | tan(x) | 正切,支持DEG/RAD模式 | | sin⁻¹ | asin(x) | 反正弦,2nd切换 | | cos⁻¹ | acos(x) | 反余弦,2nd切换 | | tan⁻¹ | atan(x) | 反正切,2nd切换 | **DEG/RAD 模式**: - 默认 DEG(角度制),按键切换 - 显示区域有 DEG/RAD 指示器 - 内部统一用 RAD 计算:RAD = DEG × π/180 ### 3.2 对数与指数 | 按键 | 函数 | 说明 | |------|------|------| | log | log₁₀(x) | 常用对数,x > 0 | | ln | ln(x) | 自然对数,x > 0 | | x² | x² | 平方 | | x³ | x³ | 立方 | | xʸ | x^y | 任意次幂(双目运算) | | e^x | eˣ | 指数函数(常数e为底的幂),2nd+ln 切换 | ### 3.3 根号 | 按键 | 函数 | 说明 | |------|------|------| | √ | √x | 平方根,x ≥ 0 | | ³√ | ³√x | 立方根 | | x√y | y√x | N次方根(双目运算) | ### 3.4 其他数学函数 | 按键 | 函数 | 说明 | |------|------|------| | n! | x! | 阶乘,非负整数;大数用 gamma 函数近似 | | 1/x | 1/x | 倒数 | | \|x\| | abs(x) | 绝对值 | | % | x% | 百分比(除以100) | | ± | -x | 取反 | | ( ) | 括号 | 改变运算优先级 | ### 3.5 常数 | 按键 | 值 | 说明 | |------|-----|------| | π | 3.14159265358979 | 圆周率 | | e | 2.71828182845905 | 自然常数 | ### 3.6 记忆功能 | 按键 | 功能 | 说明 | |------|------|------| | MC | Memory Clear | 清除记忆(设为0) | | MR | Memory Recall | 读取记忆值到当前显示 | | M+ | Memory Add | 当前值加到记忆 | | M− | Memory Subtract | 当前值从记忆减去 | **状态指示**:记忆值 ≠ 0 时,显示区有 "M" 标记。 ### 3.7 角度模式切换 - 按键:DEG ↔ RAD(同一个按键切换) - 影响:sin/cos/tan 的计算方式 - 显示:当前模式显示在 display 区域 ### 3.8 反函数模式(2nd) - 按键:2nd(切换键) - 效果:sin→sin⁻¹, cos→cos⁻¹, tan→tan⁻¹, x²→x³, √→³√, xʸ→x√y - 视觉:激活时按键背景变为 #6366f1,文字变白,表示反函数模式开启 ## 4. UI 设计 ### 4.1 布局(方案 B · 模式切换式) - 宽度:保持 460px 不变 - 4列网格布局 - 顶部增加模式切换标签栏:基础 / 科学 - 基础模式:显示原有基础键盘 - 科学模式:在数字键上方显示科学函数区 ### 4.2 模式切换标签栏 ``` ┌────────────────────────────────────────────┐ │ [ 基础 ] [ 科学 ] DEG/RAD │ ← 模式切换 + 角度模式 ├────────────────────────────────────────────┤ │ │ │ Display 区域 │ │ │ ├────────────────────────────────────────────┤ │ sin │ cos │ tan │ log │ ← 科学函数行 │ ├──────┼─────┼─────┼─────┤ │ │ 7 │ 8 │ 9 │ ÷ │ ← 数字键盘 │ ├──────┼─────┼─────┼─────┤ │ │ 4 │ 5 │ 6 │ × │ │ ├──────┼─────┼─────┼─────┤ │ │ 1 │ 2 │ 3 │ − │ │ ├──────┼─────┼─────┼─────┤ │ │ ± │ 0 │ . │ + │ │ ├──────┼─────┼─────┼─────┤ │ │ √ │ AC │ ( │ ) │ ← 功能键 │ ├──────┼─────┼─────┼─────┤ │ │ = │ π │ e │ % │ │ └──────┴─────┴─────┴─────┘ ``` ### 4.3 按键分类配色 | 类型 | 背景色 | 文字色 | 示例 | |------|--------|--------|------| | 数字键 | #1e2538 | #cbd5e1 | 0-9, . | | 三角函数 | rgba(99,102,241,0.12) | #a5b4fc | sin, cos, tan | | 对数/指数 | rgba(139,92,246,0.12) | #c4b5fd | log, ln, xʸ | | 记忆功能 | rgba(34,197,94,0.1) | #86efac | MC, MR, M+, M− | | 运算符 | rgba(14,165,233,0.1) | #7dd3fc | +, −, ×, ÷ | | 等号 | 渐变(#6366f1, #8b5cf6) | #fff | = | | 清除 | #1e2538 | #fca5a5 | AC | ### 4.4 Display 区域扩展 ``` ┌────────────────────────────────────────────┐ │ DEG M history │ ← 状态栏 │ 12 + 8 = │ ← 历史 │ 20 │ ← 当前值 └────────────────────────────────────────────┘ ``` ## 5. 状态管理 ```typescript interface CalculatorState { current: string; // 当前显示值(字符串用于保持精度) previous: string; // 上一个值(双目运算) operator: Operator | null; // 当前二元运算符 overwrite: boolean; // 是否覆盖当前输入 history: string; // 历史表达式显示 memory: number; // 记忆存储值 angleMode: 'DEG' | 'RAD'; // 角度/弧度模式 invMode: boolean; // 反函数模式(2nd键) parenOpen: boolean; // 是否有未闭合的括号 mode: 'basic' | 'scientific'; // 当前模式 } type Operator = '+' | '-' | '*' | '/' | '^' | 'root'; ``` ### 5.1 状态转换 ``` 单目运算 (sin, √, x², n!, ...): current → f(current) → current (overwrite=true) 双目运算选择 (+, −, ×, ÷, xʸ, x√y): previous ← current operator ← op overwrite ← true 等号按下: current ← compute(previous, current, operator) previous ← "" operator ← null ``` ### 5.2 角度模式影响 ```typescript const toRad = (val: number) => angleMode === 'DEG' ? val * Math.PI / 180 : val; const fromRad = (val: number) => angleMode === 'DEG' ? val * 180 / Math.PI : val; // sin 实现 const sin = (val: number) => Math.sin(toRad(val)); // sin⁻¹ 实现 const asin = (val: number) => fromRad(Math.asin(val)); ``` ## 6. 错误处理 | 错误场景 | 处理 | |----------|------| | 负数开平方根 | message.error + 显示 "Error" | | log(0) 或 log(负数) | 显示 "Error" | | tan(90°) 等无定义点 | 显示 "Error" | | 除以零 | 显示 "Error" | | 阶乘(负数/非整数过大) | gamma 近似或显示 "Error" | | 数值溢出 | 使用 toExponential(8) 显示 | ## 7. 文件变更 ### 7.1 修改文件 - `src/pages/Calculator/Calculator.tsx`:扩展 CalculatorDesktop 组件 - `src/pages/Calculator/Calculator.css`:新增科学函数按键样式、扩展布局 ### 7.2 不修改 - `src/pages/Calculator/CalculatorMobile.tsx`:保持现有基础布局 - 其他组件 ## 8. 实现顺序 1. 新增模式切换标签栏组件和样式 2. 状态扩展:添加 mode, memory, angleMode, invMode, parenOpen 3. 单目函数:sin/cos/tan/log/ln/x²/x³/√/n!/1/x/±/% 4. 双目函数:xʸ/x√y(需要特殊处理运算顺序) 5. 常数:π/e 6. 记忆功能:MC/MR/M+/M− 7. 角度模式:DEG/RAD 切换 + 指示器 8. 反函数:2nd 切换 + 按键文字变化 9. 括号:( ) 支持 10. 显示扩展:状态栏(DEG/RAD, M) ## 9. 测试要点 - 基础四则运算回归测试 - 三角函数在 DEG/RAD 模式下的正确性 - 连续运算(如 sin(30) + cos(60)) - 错误输入处理 - 记忆功能正确性 - 状态显示同步 - 模式切换正确性