You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

仅使用有符号int运算的自定义sine函数出现±1偏移错误问题

错误触发原因
  • 核心原因是有符号整数除法的截断方向偏差:C++标准规定有符号整数除法向0截断,你在泰勒展开项的连续乘除计算中,负数区间的除法每次都会多截断掉一部分值,误差累积后当s≥0.9时,缩放后的k=900刚好让累积误差跨过±1的阈值,就会出现固定间隔的±1偏移跳变。
  • 次要原因是常量缩放的精度丢失:你当前写死s=0.9,pi=314159*0.9/100的浮点结果为2827.431,直接转整数截断为2827,tau同理截断为5654,这部分系统误差和泰勒展开的截断误差叠加,刚好在每间隔约1弧度的位置触发错误。
  • 隐藏原因是32位整数溢出:p的最大取值约为2827,计算a7项时需要连续乘6次p,28276远大于32位有符号int的最大值(231-1≈21亿),溢出后的有符号整数属于未定义行为,会进一步放大结果偏差。
修复方案
  1. 替换所有整数除法为四舍五入实现:将直接/操作替换为带四舍五入的整数除法,避免向0截断带来的累积误差,实现逻辑为:
long long round_div(long long a, long long b) {
    return (a >= 0 ? (a + b / 2) : (a - b / 2)) / b;
}
  1. 中间计算改用64位整数:将a3/a5/a7的类型改为long long,避免乘法溢出。
  2. 优化pi/tau的缩放逻辑:用纯整数运算实现缩放,避免浮点转整数的截断误差。
修复后核心代码示例
long long round_div(long long a, long long b) {
    return (a >= 0 ? (a + b / 2) : (a - b / 2)) / b;
}

int sin(int x, int s1, int s2)
{
  long long p = x;
  long long pi = 314159;
  long long k = 1000;
  long long tau = 628318;
  const long long six = 6;
  const long long oneHundredTwenty = 120;
  const long long fiveThousandFourty = 5040;
  long long ans;
  long long a3;
  long long a5;
  long long a7;
  const int s = 90; // 用整数缩放代替浮点0.9,避免精度损失

  pi = round_div(pi * s, 10000);
  tau = round_div(tau * s, 10000);
  k = round_div(k * s, 100);

  p %= tau;
  p -= pi;

  a3 = p;
  a5 = p;
  a7 = p;

  ans = p;

  a3 = round_div(a3 * p, k);
  a3 = round_div(a3 * p, k);
  a3 = round_div(a3, six);

  a5 = round_div(a5 * p, k);
  a5 = round_div(a5 * p, k);
  a5 = round_div(a5 * p, k);
  a5 = round_div(a5 * p, k);
  a5 = round_div(a5, oneHundredTwenty);

  a7 = round_div(a7 * p, k);
  a7 = round_div(a7 * p, k);
  a7 = round_div(a7 * p, k);
  a7 = round_div(a7 * p, k);
  a7 = round_div(a7 * p, k);
  a7 = round_div(a7 * p, k);
  a7 = round_div(a7, fiveThousandFourty);

  ans -= a3;
  ans += a5;
  ans -= a7;

  return 30 + round_div(ans, 33);
}

内容的提问来源于stack exchange,提问作者RawSteak0

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 20:36:02