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

寻求|x|<π/4范围内tan(x)的双精度1 ULP逼近优化方案

寻求|x|<π/4范围内tan(x)的1 ULP精度有理逼近

需求说明

  • 目标逼近形式:tan(x) = x * P(x²) / Q(x²),其中P、Q均为x²的三次多项式
  • 约束条件:
    • 必须满足x=0处函数值与梯度匹配(即P₀=Q₀,保证极小x时tan(x)≈x)
    • 理想情况满足x=π/4处匹配,目前可放宽此处梯度约束
    • 优先保留某一x⁶项系数为1.0以节省乘法运算,若为达到16位有效十进制精度可放宽此要求

当前误差表现

通过Pade逼近结合模拟退火得到的系数,在x≈0.14处存在相对误差尖峰(约5.5e-16),十亿次随机测试中约60个样本超出阈值,误差直方图如下:

-5.5511e-16 | 0
-4.4409e-16 | 704272
-3.3307e-16 | 0
-2.2204e-16 | 157067630
-1.1102e-16 | 0
 0.0000e+00 | 485332167
 1.1102e-16 | 240168741
 2.2204e-16 | 99172390
 3.3307e-16 | 16874505
 4.4409e-16 | 680236
 5.5511e-16 | 59
 6.6613e-16 | 0

 Mean  1.94185e-17   StdDev  1.31764e-16   Entropy 1.29231

已尝试的三种逼近系数

Pade逼近系数

Pade0 (1)1 (x²)2 (x⁴)3 (x⁶)
Pn135135-17325378-1
Qn135135-623703150-28

十进制系数Remez逼近系数

Remez0 (1)1 (x²)2 (x⁴)3 (x⁶)
Pn133506.920100216-17127.5484486707374.700589646508-1
Qn133506.920100216-61629.85514874173117.06295917985-27.8423369154197

高精度十六进制Remez*逼近系数

Remez*0 (1)1 (x²)2 (x⁴)3 (x⁶)
Pn0x1.04c175c5d80a5p+17-0x1.0b9e319c87430p+140x1.76b359d7d3ac0p+8-1
Qn0x1.04c175c5d80a5p+17-0x1.e17bb5d60e518p+150x1.85a203c2f84f8p+11-0x1.bd7a3645ff105p+4

示例实现代码

// Toy_Pade.cpp : Demonstrates the failing cases err>5.5e-16 and prints out failures
//
#define _USE_MATH_DEFINES
#include <stdio.h>
#include <math.h>

double TanPQ(double x)
{
  const double P[4] = { 133506.920100216, -17127.548448670765,  374.700589646508, -1.0 };
  const double Q[4] = { 133506.920100216, -61629.8551487418,    3117.06295917985, -27.84233691541965 };

  double sumP, sumQ, x2;
  int i;
  sumP = sumQ = 0;
  x2 = x * x;
  for (i = 3; i >= 0; i--)
  {
     sumP = sumP * x2 + P[i];
     sumQ = sumQ * x2 + Q[i];
  }
  return x * sumP / sumQ;
}

double tan87_diff(double x)
// return x86 fptan x forced to the x87 coprocessor or tanl()
{
  long double y,t;
  if (x == 0) return 0;
  t = TanPQ(x);
  #ifdef _M_IX86
  _asm {
         fld qword ptr[x]
         fptan
         fxch st(1)  // save the 1
         fdivr qword ptr[t]
         fsubp st(1), st
         fstp qword ptr[y]
   }
  #else
  y = 1 - t / tanl(x);
 #endif
 return y;
}

int main()
{
  double x, dx, err;
  dx = M_PI / 2000000000;
  x = 0;
  while (x < M_PI / 4)
  {
     err = tan87_diff(x);
     if (fabs(err) > 5.0e-16) printf("%-26.18g %22.14a %g\n", x, x, err);
     x = x + dx;
  }
}

优化难点与求助方向

  • 瓶颈:最终优化阶段存在大量局部最优解,难以收敛到1 ULP精度
  • 潜在方案:LLL方法可能有效,但暂无实现能力
  • 寻求支持:
    • Intel LLL优化包、Sollya、ARM Remez包的使用指导
    • 更优的逼近方案设计
    • 启发式优化建议

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 21:47:10