diff --git a/charter-std/utils/math.ch b/charter-std/utils/math.ch index 9f6cea6..aed2369 100644 --- a/charter-std/utils/math.ch +++ b/charter-std/utils/math.ch @@ -1,228 +1,73 @@ -///! # 数学运算库 -///! -///! Math Utilities -///! 提供安全的数学运算函数 -///! -///! **版本**: v1.0 -///! **模块**: charter-std/utils/math.ch - -// ============================================================================ -// 安全算术运算 -// ============================================================================ - -/// 安全加法(检查溢出) -/// -/// # 参数 -/// - `a`: 第一个数 -/// - `b`: 第二个数 -/// -/// # 返回 -/// - `u256`: 和 -/// -/// # Panics -/// - 如果发生溢出 pub fn safe_add(a: u256, b: u256) -> u256 { let result = a + b; require(result >= a, "Addition overflow"); return result; } -/// 安全减法(检查下溢) -/// -/// # 参数 -/// - `a`: 被减数 -/// - `b`: 减数 -/// -/// # 返回 -/// - `u256`: 差 -/// -/// # Panics -/// - 如果发生下溢 pub fn safe_sub(a: u256, b: u256) -> u256 { require(a >= b, "Subtraction underflow"); return a - b; } -/// 安全乘法(检查溢出) -/// -/// # 参数 -/// - `a`: 第一个数 -/// - `b`: 第二个数 -/// -/// # 返回 -/// - `u256`: 积 -/// -/// # Panics -/// - 如果发生溢出 pub fn safe_mul(a: u256, b: u256) -> u256 { if a == 0 { return 0; } - let result = a * b; require(result / a == b, "Multiplication overflow"); return result; } -/// 安全除法(检查除零) -/// -/// # 参数 -/// - `a`: 被除数 -/// - `b`: 除数 -/// -/// # 返回 -/// - `u256`: 商 -/// -/// # Panics -/// - 如果除数为0 pub fn safe_div(a: u256, b: u256) -> u256 { require(b > 0, "Division by zero"); return a / b; } -/// 安全取模(检查除零) -/// -/// # 参数 -/// - `a`: 被除数 -/// - `b`: 除数 -/// -/// # 返回 -/// - `u256`: 余数 -/// -/// # Panics -/// - 如果除数为0 pub fn safe_mod(a: u256, b: u256) -> u256 { require(b > 0, "Modulo by zero"); return a % b; } -// ============================================================================ -// 比较函数 -// ============================================================================ - -/// 返回两个数中的最大值 -/// -/// # 参数 -/// - `a`: 第一个数 -/// - `b`: 第二个数 -/// -/// # 返回 -/// - `u256`: 最大值 pub fn max(a: u256, b: u256) -> u256 { return if a >= b { a } else { b }; } -/// 返回两个数中的最小值 -/// -/// # 参数 -/// - `a`: 第一个数 -/// - `b`: 第二个数 -/// -/// # 返回 -/// - `u256`: 最小值 pub fn min(a: u256, b: u256) -> u256 { return if a <= b { a } else { b }; } -/// 计算绝对差值 -/// -/// # 参数 -/// - `a`: 第一个数 -/// - `b`: 第二个数 -/// -/// # 返回 -/// - `u256`: 绝对差值 pub fn abs_diff(a: u256, b: u256) -> u256 { return if a >= b { a - b } else { b - a }; } -// ============================================================================ -// 百分比和比例计算 -// ============================================================================ - -/// 计算百分比(使用基点,1基点 = 0.01%) -/// -/// # 参数 -/// - `amount`: 数量 -/// - `basis_points`: 基点(0-10000,10000 = 100%) -/// -/// # 返回 -/// - `u256`: 结果 -/// -/// # 示例 -/// ``` -/// let result = percentage(1000, 500); // 1000 * 5% = 50 -/// ``` pub fn percentage(amount: u256, basis_points: u16) -> u256 { require(basis_points <= 10000, "Basis points must be <= 10000"); return safe_mul(amount, basis_points as u256) / 10000; } -/// 计算比例 -/// -/// # 参数 -/// - `amount`: 数量 -/// - `numerator`: 分子 -/// - `denominator`: 分母 -/// -/// # 返回 -/// - `u256`: 结果 -/// -/// # 示例 -/// ``` -/// let result = proportion(1000, 3, 4); // 1000 * 3/4 = 750 -/// ``` pub fn proportion(amount: u256, numerator: u256, denominator: u256) -> u256 { require(denominator > 0, "Denominator cannot be zero"); return safe_mul(amount, numerator) / denominator; } -/// 向上取整除法 -/// -/// # 参数 -/// - `a`: 被除数 -/// - `b`: 除数 -/// -/// # 返回 -/// - `u256`: 向上取整的商 pub fn ceil_div(a: u256, b: u256) -> u256 { require(b > 0, "Division by zero"); - if a == 0 { return 0; } - return (a - 1) / b + 1; } -// ============================================================================ -// 幂运算 -// ============================================================================ - -/// 计算幂(a^b) -/// -/// # 参数 -/// - `base`: 底数 -/// - `exponent`: 指数 -/// -/// # 返回 -/// - `u256`: 结果 -/// -/// # Panics -/// - 如果发生溢出 pub fn pow(base: u256, exponent: u256) -> u256 { if exponent == 0 { return 1; } - if base == 0 { return 0; } - let mut result: u256 = 1; let mut b = base; let mut e = exponent; - while e > 0 { if e % 2 == 1 { result = safe_mul(result, b); @@ -230,247 +75,99 @@ pub fn pow(base: u256, exponent: u256) -> u256 { b = safe_mul(b, b); e = e / 2; } - return result; } -/// 计算平方根(整数部分) -/// -/// # 参数 -/// - `x`: 被开方数 -/// -/// # 返回 -/// - `u256`: 平方根的整数部分 -/// -/// # 算法 -/// 使用牛顿迭代法 pub fn sqrt(x: u256) -> u256 { if x == 0 { return 0; } - if x <= 3 { return 1; } - - // 初始猜测值 let mut z = x; let mut y = (x + 1) / 2; - - // 牛顿迭代 while y < z { z = y; y = (x / y + y) / 2; } - return z; } -// ============================================================================ -// 平均值计算 -// ============================================================================ - -/// 计算算术平均值 -/// -/// # 参数 -/// - `a`: 第一个数 -/// - `b`: 第二个数 -/// -/// # 返回 -/// - `u256`: 平均值 pub fn average(a: u256, b: u256) -> u256 { - // (a + b) / 2 可能溢出,使用 (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2) return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2); } -/// 计算加权平均值 -/// -/// # 参数 -/// - `values`: 数值数组 -/// - `weights`: 权重数组 -/// -/// # 返回 -/// - `u256`: 加权平均值 -/// -/// # Panics -/// - 如果数组长度不匹配 -/// - 如果权重总和为0 pub fn weighted_average(values: Vec, weights: Vec) -> u256 { require(values.len() == weights.len(), "Arrays length mismatch"); require(values.len() > 0, "Arrays cannot be empty"); - let mut sum: u256 = 0; let mut weight_sum: u256 = 0; - for i in 0..values.len() { sum = safe_add(sum, safe_mul(values[i], weights[i])); weight_sum = safe_add(weight_sum, weights[i]); } - require(weight_sum > 0, "Weight sum cannot be zero"); - return sum / weight_sum; } -// ============================================================================ -// 数组统计函数 -// ============================================================================ - -/// 计算数组总和 -/// -/// # 参数 -/// - `values`: 数值数组 -/// -/// # 返回 -/// - `u256`: 总和 pub fn sum(values: Vec) -> u256 { let mut result: u256 = 0; - for value in values { result = safe_add(result, value); } - return result; } -/// 查找数组最大值 -/// -/// # 参数 -/// - `values`: 数值数组 -/// -/// # 返回 -/// - `u256`: 最大值 -/// -/// # Panics -/// - 如果数组为空 pub fn array_max(values: Vec) -> u256 { require(values.len() > 0, "Array cannot be empty"); - let mut max_value = values[0]; - for value in values { if value > max_value { max_value = value; } } - return max_value; } -/// 查找数组最小值 -/// -/// # 参数 -/// - `values`: 数值数组 -/// -/// # 返回 -/// - `u256`: 最小值 -/// -/// # Panics -/// - 如果数组为空 pub fn array_min(values: Vec) -> u256 { require(values.len() > 0, "Array cannot be empty"); - let mut min_value = values[0]; - for value in values { if value < min_value { min_value = value; } } - return min_value; } -// ============================================================================ -// 金融计算函数 -// ============================================================================ - -/// 计算复利 -/// -/// # 参数 -/// - `principal`: 本金 -/// - `rate_basis_points`: 利率(基点,1基点 = 0.01%) -/// - `periods`: 计息期数 -/// -/// # 返回 -/// - `u256`: 本息和 -/// -/// # 公式 -/// A = P * (1 + r)^n -pub fn compound_interest( - principal: u256, - rate_basis_points: u16, - periods: u256 -) -> u256 { +pub fn compound_interest(principal: u256, rate_basis_points: u16, periods: u256) -> u256 { require(rate_basis_points <= 10000, "Rate must be <= 100%"); - if periods == 0 { return principal; } - - // 使用基点计算:(10000 + rate) / 10000 let rate_factor = 10000 + (rate_basis_points as u256); let mut result = principal; - for _ in 0..periods { result = safe_mul(result, rate_factor) / 10000; } - return result; } -/// 计算单利 -/// -/// # 参数 -/// - `principal`: 本金 -/// - `rate_basis_points`: 利率(基点) -/// - `periods`: 计息期数 -/// -/// # 返回 -/// - `u256`: 本息和 -/// -/// # 公式 -/// A = P * (1 + r * n) -pub fn simple_interest( - principal: u256, - rate_basis_points: u16, - periods: u256 -) -> u256 { +pub fn simple_interest(principal: u256, rate_basis_points: u16, periods: u256) -> u256 { require(rate_basis_points <= 10000, "Rate must be <= 100%"); - - let interest = safe_mul( - safe_mul(principal, rate_basis_points as u256), - periods - ) / 10000; - + let interest = safe_mul(safe_mul(principal, rate_basis_points as u256), periods) / 10000; return safe_add(principal, interest); } -/// 计算年化收益率(APY) -/// -/// # 参数 -/// - `initial_value`: 初始价值 -/// - `final_value`: 最终价值 -/// - `days`: 天数 -/// -/// # 返回 -/// - `u16`: 年化收益率(基点) -pub fn calculate_apy( - initial_value: u256, - final_value: u256, - days: u256 -) -> u16 { +pub fn calculate_apy(initial_value: u256, final_value: u256, days: u256) -> u16 { require(initial_value > 0, "Initial value must be positive"); require(days > 0, "Days must be positive"); - if final_value <= initial_value { return 0; } - - // APY = ((final / initial) - 1) * (365 / days) * 10000 let gain = final_value - initial_value; let return_rate = safe_mul(gain, 10000) / initial_value; let apy = safe_mul(return_rate, 365) / days; - return min(apy, 10000) as u16; }