import Big from ‘big.js’;
import { z } from ‘zod’;
// 定义参数校验规则
// 兼容:数字、合法的数字字符串(如 ‘12.34’)
// 拒绝:NaN, Infinity, 纯字母字符串, 对象, 数组等
const NumberCoerceSchema = z
.union([
z.number().finite(), // 必须是有限的数字
z.string().regex(/^-?\d+(.\d+)?$/, “无效的数字格式”) // 必须是合法的数字字符串
])
.transform((val) => new Big(val)); // 校验通过后直接转换为 Big 对象
/**
加法函数
@param {number|string} a - 加数 A (默认 0)
@param {number|string} b - 加数 B (默认 0)
@returns {string} 以字符串形式返回精确结果,避免大数失真
*/
function ultimateSum(a = 0, b = 0) {
try {
// 运行时强校验并解析
const bigA = NumberCoerceSchema.parse(a);
const bigB = NumberCoerceSchema.parse(b);// 使用 big.js 进行高精度加法
return bigA.plus(bigB).toString();
} catch (error) {
if (error instanceof z.ZodError) {
// 结构化抛出异常,方便前端输入框或日志捕获具体是哪个参数错了
throw new TypeError(参数校验失败: ${JSON.stringify(error.format())});
}
throw error;
}
}
// === 测试用例 ===
// 1. 浮点数高精度测试
console.log(ultimateSum(0.1, 0.2)); // “0.3” (完美)
console.log(ultimateSum(0.111, 0.222)); // “0.333”
// 2. 字符串与数字混用
console.log(ultimateSum(‘1.5’, 2.5)); // “4”
// 3. 缺省值测试
console.log(ultimateSum(5)); // “5”
console.log(ultimateSum()); // “0”
// 4. 超大数字测试(超过 JS 安全整数限制)
console.log(ultimateSum(‘9007199254740991’, 1)); // “9007199254740992”
// === 错误拦截测试 (均会抛出语义明确的错误) ===
// ultimateSum(1, NaN); // 报错: 参数校验失败 (finite 校验不通过)
// ultimateSum(1, ‘abc’); // 报错: 参数校验失败 (regex 校验不通过)
// ultimateSum(1, {}); // 报错: 参数校验失败 (类型不匹配)