标题: FPU_MATH.H双精度数学库 [打印本页]
作者: happy886rr 时间: 2017-2-1 02:47 标题: FPU_MATH.H双精度数学库
本帖最后由 happy886rr 于 2017-2-1 02:56 编辑
发现FPU指令集速度惊人,比直接调用math.h计算快一倍,因此查阅了intel的技术文档,对该指令集做了内联封装,成为单一头文件,直接include就可使用。也弥补了VS编译器没有双曲函数系的通病。部分函数实现的很仓促,如有疏漏,在所难免。FPU指令集版权归intel所有,本人只做封装,个别数学函数做了粗糙的实现,但精度分毫不差,后续将推出超double类型即 super double型的新型数学库,采用混合数据压缩技术,届时将支持万位精度。
摘要:
=============================================================================
FPU双精度数学库。即FPU指令集内联汇编。比MATH.H速度快一倍。部分函数实现仅凭
数学定义、未做严密测试,若有计算出入,请自行完善。
=============================================================================
用法:
-----------------------------------------------------------------------------
#include "FPU_MATH.H"
-----------------------------------------------------------------------------
备注:需CPU支持FPU浮点加速指令,传入传出均为double型。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
常数类
FPU_PI 3.1415926535897932
FPU_E 2.7182818284590452
通用类
FPU_random随机数
FPU_round 四舍五入
FPU_ceil 向上舍入
FPU_floor 向下舍入
FPU_abs 绝对值
FPU_sqrt 开方
FPU_log10 常用对数,以10为底
FPU_log2 2底对数
FPU_log 自然对数
FPU_exp e的次幂
FPU_torad 度转弧度
三角函数类
FPU_sin、FPU_cos、FPU_tan
FPU_arcsin、FPU_arccos、FPU_arctan
双曲函数类
FPU_sinh、FPU_cosh、FPU_tanh
FPU_arcsinh、FPU_arccosh、FPU_arctanh
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2017-02-01
FPU_MATH.H源码。仅单一头文件,方便调用。- /*
- FPU_MATH.H COPYRIGHT@2017~2019 BY HAPPY
- */
-
- //常数定义
- #define FPU_PI 3.1415926535897932
- #define FPU_E 2.7182818284590452
-
- //正弦函数
- double FPU_sin(double x)
- {
- double FPU_RET;
- __asm__
- (
- "fsin\n"
- : "=t" (FPU_RET)
- : "0" (x)
- );
- return FPU_RET;
- }
-
- //余弦函数
- double FPU_cos(double x)
- {
- double FPU_RET;
- __asm__
- (
- "fcos\n"
- : "=t" (FPU_RET)
- : "0" (x)
- );
- return FPU_RET;
- }
-
- //正切函数
- double FPU_tan(double x)
- {
- double FPU_RET, FPU_VAL;
- __asm__
- (
- "fptan\n"
- : "=t" (FPU_VAL),
- "=u" (FPU_RET)
- : "0" (x)
- );
- return FPU_RET;
- }
-
- //ABS函数
- double FPU_fabs(double x)
- {
- double FPU_RET;
- __asm__
- (
- "fabs\n"
- : "=t" (FPU_RET)
- : "0" (x)
- );
- return FPU_RET;
- }
-
- //自然对数
- double FPU_log2(double x)
- {
- double FPU_RET;
- __asm__
- (
- "fld1\n"
- "fxch\n"
- "fyl2x\n"
- : "=t" (FPU_RET)
- : "0" (x)
- );
- return FPU_RET;
- }
-
- //自然对数
- double FPU_log(double x)
- {
- double FPU_RET;
- __asm__
- (
- "fldln2\n"
- "fxch\n"
- "fyl2x\n"
- : "=t" (FPU_RET)
- : "0" (x)
- );
- return FPU_RET;
- }
-
- //常用对数
- double FPU_log10(double x)
- {
- double FPU_RET;
- __asm__
- (
- "fldlg2\n"
- "fxch\n"
- "fyl2x\n"
- : "=t" (FPU_RET)
- : "0" (x)
- );
- return FPU_RET;
- }
-
- //开方函数
- double FPU_sqrt(double x)
- {
- double FPU_RET;
- __asm__
- (
- "fsqrt\n"
- : "=t" (FPU_RET)
- : "0" (x)
- );
- return FPU_RET;
- }
-
- //EXP函数
- double FPU_exp(double x)
- {
- double FPU_RET, FPU_VAL;
- __asm__
- (
- "fldl2e\n"
- "fmul %%st(1)\n"
- "fst %%st(1)\n"
- "frndint\n"
- "fxch;\n"
- "fsub %%st(1)\n"
- "f2xm1\n"
- : "=t" (FPU_RET), "=u" (FPU_VAL)
- : "0" (x)
- );
- FPU_RET+= 1.0f;
- __asm__
- (
- "fscale\n"
- : "=t" (FPU_RET)
- : "0" (FPU_RET), "u" (FPU_VAL)
- );
- return FPU_RET;
- }
-
- //次方函数
- double FPU_pow(double x, double y)
- {
- double FPU_RET, FPU_VAL;
- double FPU_RES=1.0f;
- int FPU_INT=(int)y;
- if (x==0.0 && y >0.0){return 0.0;}
- if (y==(double)FPU_INT){
- if(FPU_INT==0){return 1.0;}
- if(FPU_INT <0){FPU_INT=-FPU_INT, x=1.0/x;}
- while(1){
- if(FPU_INT&1){FPU_RES*=x;}
- FPU_INT>>=1;
- if(FPU_INT==0){return FPU_RES;}
- x*=x;
- }
- }
- __asm__
- (
- "fmul %%st(1)\n"
- "fst %%st(1)\n"
- "frndint;\n"
- "fxch;\n"
- "fsub %%st(1);\n"
- "f2xm1;\n"
- : "=t" (FPU_RET), "=u" (FPU_VAL)
- : "0" (FPU_log2(x)), "1" (y)
- );
- FPU_RET+=1.0;
- __asm__
- (
- "fscale"
- : "=t" (FPU_RET)
- : "0" (FPU_RET), "u" (FPU_VAL)
- );
- return FPU_RET;
- }
-
- //四舍五入
- double FPU_round(double x)
- {
- return (x<=0)?(float)((int)(x-0.5)):(float)((int)(x+0.5));
- }
-
- //向下取整
- double FPU_floor(double x)
- {
- return (x<0)?(float)((int)x)-1:(float)((int)x);
- }
-
- //向上取整
- double FPU_ceil(double x)
- {
- return (x<=0)?(float)((int)x):(float)((int)x)+1;
- }
-
- //双目反正切
- double FPU_atan2(double x, double y)
- {
- double FPU_RET;
- __asm__
- (
- "fpatan\n"
- "fld %%st(0)"
- : "=t" (FPU_RET)
- : "0" (y), "u" (x)
- );
- return FPU_RET;
- }
-
- //反正弦函数
- double FPU_asin(double x)
- {
- return FPU_atan2(x,FPU_sqrt(1.0-x*x));
- }
-
- //反余弦函数
- double FPU_acos(double x)
- {
- return FPU_atan2(FPU_sqrt(1.0-x*x), x);
- }
-
- //反正切函数
- double FPU_atan(double x)
- {
- return FPU_atan2(x,1.0f);
- }
-
- //双曲正弦函数
- double FPU_sinh(double x)
- {
- return (FPU_exp(x)-FPU_exp(-x))/2;
- }
-
- //双曲余弦函数
- double FPU_cosh(double x)
- {
- return (FPU_exp(x)+FPU_exp(-x))/2;
- }
-
- //双曲正切函数
- double FPU_tanh(double x)
- {
- return (FPU_exp(x)-FPU_exp(-x))/(FPU_exp(x)+FPU_exp(-x));
- }
-
- //反双曲正弦函数
- double FPU_asinh(double x)
- {
- return FPU_log(x+FPU_sqrt(x*x+1));
- }
-
- //反双曲余弦函数
- double FPU_acosh(double x)
- {
- return FPU_log(x+FPU_sqrt(x*x-1));
- }
-
- //反双曲正切函数
- double FPU_atanh(double x)
- {
- return FPU_log((1+x)/(1-x))/2;
- }
-
- //度转弧度
- double FPU_torad(double x)
- {
- return x*FPU_PI/180;
- }
-
- //随机数函数
- double FPU_random(double x)
- {
- return (x<2)?rand()%8192/8192.0:rand()%(int)(x);
- }
复制代码
作者: B魔方大人 时间: 2017-2-1 18:46
如果使用math.h
优化的时候启用SSE试试如何!
欢迎光临 批处理之家 (http://bbs.bathome.net/) |
Powered by Discuz! 7.2 |