Assembly 使用泰勒展开的sin(x)的汇编代码
在x86Linux中,如何使用Taylor扩展在汇编代码中实现sin(x)Assembly 使用泰勒展开的sin(x)的汇编代码,assembly,x86,trigonometry,Assembly,X86,Trigonometry,在x86Linux中,如何使用Taylor扩展在汇编代码中实现sin(x) 它有两个用于计算近似sin(x)值的算法,包括C和汇编版本。当然,这是ARM组装,但是它的要点应该很容易翻译成x86或类似的版本。您没有说明是哪种CPU体系结构,所以我假设是x86 最简单(可能也是最低效)的方法是用RPN编写公式,它几乎可以直接映射到FPU指令 例如 代数公式:x-(x^3/3!)+(x^5/5!) RPN:x x x*x*3 2*/-x x*x*x*x*5 4*3*2*/+ 即: fld x fld
它有两个用于计算近似sin(x)值的算法,包括C和汇编版本。当然,这是ARM组装,但是它的要点应该很容易翻译成x86或类似的版本。您没有说明是哪种CPU体系结构,所以我假设是x86 最简单(可能也是最低效)的方法是用RPN编写公式,它几乎可以直接映射到FPU指令 例如 代数公式:x-(x^3/3!)+(x^5/5!) RPN:x x x*x*3 2*/-x x*x*x*x*5 4*3*2*/+ 即:
fld x
fld x
fld x
fmul
fld x
fmul
fild [const_3]
fild [const_2]
fmul
fdiv
fsub
fld x
fld x
fmul
fld x
fmul
fld x
fmul
fld x
fmul
fild [const_5]
fild [const_4]
fmul
fild [const_3]
fmul
fild [const_2]
fmul
fdiv
fadd
有一些明显的优化策略-
- 而不是计算x,xxx, xxxxx等,对于每个术语,存储一个 “运行乘积”和乘法 每次x*x
- 而不是 计算每个变量的阶乘 术语,执行相同的“运行产品”
fldz ; 0
fld1 ; 1, 0
--剪断--
为什么??自从80387(大约1987年)处理器问世以来,已经有了FCOS和FSIN操作码 资料来源: 维基百科
演示场景中的私人朋友有人给我指出了初学者数学的方向。。请这个链接让我做噩梦:)@dark-star1:看看-有一组关于微积分播放列表一半的近似函数的视频,其中有涉及到它的每一个数学层次的视频。几年前做过一次。。。问题是不使用
fsin
来计算SIN,因为要求使用泰勒级数来近似它。最好使用fcos和fsin,因为它们比任何可以在C/C++中创建并且可以在一个周期内执行的东西都快得多,而泰勒方法则慢得多。但这不是问题所在我问了这个问题。这个问题问如何使用泰勒级数(展开式)。这是一项家庭作业,要求人们自己动手。
long double LD_COS(long double __X)
{
register long double __VALUE;
__asm__ __volatile__(
"fcos \n\t"
: "=t" (__VALUE)
: "0" (__X)
);
return __VALUE;
}
long double LD_SIN(long double __X)
{
register long double __VALUE;
__asm__ __volatile__(
"fsin \n\t"
: "=t" (__VALUE)
: "0" (__X)
);
return __VALUE;
}
$ ./taylor-sine 0.5 1
0.4791666667
$ ./taylor-sine 0.5 5
0.4794255386
$ echo "s(0.5)"|bc -l
.47942553860420300027
long double LD_COS(long double __X)
{
register long double __VALUE;
__asm__ __volatile__(
"fcos \n\t"
: "=t" (__VALUE)
: "0" (__X)
);
return __VALUE;
}
long double LD_SIN(long double __X)
{
register long double __VALUE;
__asm__ __volatile__(
"fsin \n\t"
: "=t" (__VALUE)
: "0" (__X)
);
return __VALUE;
}