找回密码
 注册
搜索
[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
查看: 9640|回复: 1

FPU_MATH.H双精度数学库

[复制链接]
发表于 2017-2-1 02:47:09 | 显示全部楼层 |阅读模式
本帖最后由 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源码。仅单一头文件,方便调用。

  1. /*
  2.         FPU_MATH.H COPYRIGHT@2017~2019 BY HAPPY
  3. */

  4. //常数定义
  5. #define FPU_PI 3.1415926535897932
  6. #define FPU_E  2.7182818284590452

  7. //正弦函数
  8. double FPU_sin(double x)
  9. {
  10.         double FPU_RET;                     
  11.         __asm__                     
  12.         (                           
  13.                 "fsin\n"              
  14.                 : "=t" (FPU_RET)   
  15.                 : "0"  (x)         
  16.         );
  17.         return FPU_RET;
  18. }

  19. //余弦函数
  20. double FPU_cos(double x)
  21. {                     
  22.         double FPU_RET;
  23.         __asm__                     
  24.         (                           
  25.                 "fcos\n"              
  26.                 : "=t" (FPU_RET)   
  27.                 : "0"  (x)         
  28.         );
  29.         return FPU_RET;
  30. }

  31. //正切函数
  32. double FPU_tan(double x)
  33. {                     
  34.         double FPU_RET, FPU_VAL;
  35.         __asm__                     
  36.         (                           
  37.                 "fptan\n"            
  38.                 : "=t" (FPU_VAL),   
  39.                   "=u" (FPU_RET)   
  40.                 : "0"  (x)         
  41.         );
  42.         return FPU_RET;
  43. }

  44. //ABS函数
  45. double FPU_fabs(double x)
  46. {                       
  47.         double FPU_RET;
  48.         __asm__                     
  49.         (                           
  50.                 "fabs\n"              
  51.                 : "=t" (FPU_RET)   
  52.                 : "0"  (x)         
  53.         );
  54.         return FPU_RET;
  55. }

  56. //自然对数
  57. double FPU_log2(double x)
  58. {                    
  59.         double FPU_RET;
  60.         __asm__                     
  61.         (                           
  62.                 "fld1\n"         
  63.                 "fxch\n"            
  64.                 "fyl2x\n"           
  65.                 : "=t" (FPU_RET)   
  66.                 : "0"  (x)         
  67.         );
  68.         return FPU_RET;
  69. }

  70. //自然对数
  71. double FPU_log(double x)
  72. {                    
  73.         double FPU_RET;
  74.         __asm__                     
  75.         (                           
  76.                 "fldln2\n"         
  77.                 "fxch\n"            
  78.                 "fyl2x\n"           
  79.                 : "=t" (FPU_RET)   
  80.                 : "0"  (x)         
  81.         );
  82.         return FPU_RET;
  83. }

  84. //常用对数
  85. double FPU_log10(double x)
  86. {                    
  87.         double FPU_RET;
  88.         __asm__                     
  89.         (                           
  90.                 "fldlg2\n"         
  91.                 "fxch\n"            
  92.                 "fyl2x\n"           
  93.                 : "=t" (FPU_RET)   
  94.                 : "0"  (x)         
  95.         );
  96.         return FPU_RET;
  97. }

  98. //开方函数
  99. double FPU_sqrt(double x)
  100. {                     
  101.         double FPU_RET;
  102.         __asm__                     
  103.         (                           
  104.                 "fsqrt\n"           
  105.                 : "=t" (FPU_RET)   
  106.                 : "0"  (x)         
  107.         );
  108.         return FPU_RET;
  109. }

  110. //EXP函数
  111. double FPU_exp(double x)
  112. {
  113.         double FPU_RET, FPU_VAL;
  114.         __asm__                     
  115.         (                           
  116.                 "fldl2e\n"         
  117.                 "fmul %%st(1)\n"   
  118.                 "fst   %%st(1)\n"  
  119.                 "frndint\n"         
  120.                 "fxch;\n"         
  121.                 "fsub %%st(1)\n"   
  122.                 "f2xm1\n"           
  123.                 : "=t" (FPU_RET), "=u" (FPU_VAL)
  124.                 : "0" (x)           
  125.                 );                  
  126.                 FPU_RET+= 1.0f;   
  127.         __asm__                     
  128.         (                           
  129.                 "fscale\n"         
  130.                 : "=t" (FPU_RET)   
  131.                 : "0" (FPU_RET), "u" (FPU_VAL)
  132.         );
  133.         return FPU_RET;
  134. }

  135. //次方函数
  136. double FPU_pow(double x, double y)
  137. {
  138.         double FPU_RET, FPU_VAL;
  139.         double FPU_RES=1.0f;
  140.         int FPU_INT=(int)y;
  141.         if (x==0.0 && y >0.0){return 0.0;}
  142.         if (y==(double)FPU_INT){
  143.                 if(FPU_INT==0){return 1.0;}
  144.                 if(FPU_INT <0){FPU_INT=-FPU_INT, x=1.0/x;}
  145.                 while(1){
  146.                         if(FPU_INT&1){FPU_RES*=x;}
  147.                         FPU_INT>>=1;
  148.                         if(FPU_INT==0){return FPU_RES;}
  149.                         x*=x;
  150.                 }
  151.         }
  152.         __asm__
  153.         (
  154.                 "fmul %%st(1)\n"
  155.                 "fst  %%st(1)\n"
  156.                 "frndint;\n"
  157.                 "fxch;\n"
  158.                 "fsub %%st(1);\n"
  159.                 "f2xm1;\n"
  160.                 : "=t" (FPU_RET), "=u" (FPU_VAL)
  161.                 : "0"  (FPU_log2(x)), "1" (y)
  162.         );
  163.         FPU_RET+=1.0;
  164.         __asm__
  165.         (
  166.                 "fscale"
  167.                 : "=t" (FPU_RET)
  168.                 : "0" (FPU_RET), "u" (FPU_VAL)       
  169.         );
  170.         return FPU_RET;
  171. }

  172. //四舍五入
  173. double FPU_round(double x)
  174. {
  175.         return (x<=0)?(float)((int)(x-0.5)):(float)((int)(x+0.5));
  176. }

  177. //向下取整
  178. double FPU_floor(double x)
  179. {
  180.         return (x<0)?(float)((int)x)-1:(float)((int)x);
  181. }

  182. //向上取整
  183. double FPU_ceil(double x)
  184. {
  185.         return (x<=0)?(float)((int)x):(float)((int)x)+1;
  186. }

  187. //双目反正切
  188. double FPU_atan2(double x, double y)
  189. {
  190.         double FPU_RET;
  191.         __asm__                     
  192.         (                           
  193.                 "fpatan\n"         
  194.                 "fld %%st(0)"     
  195.                 : "=t" (FPU_RET)  
  196.                 : "0" (y), "u" (x)  
  197.         );
  198.         return FPU_RET;
  199. }

  200. //反正弦函数
  201. double FPU_asin(double x)
  202. {
  203.         return FPU_atan2(x,FPU_sqrt(1.0-x*x));
  204. }

  205. //反余弦函数
  206. double FPU_acos(double x)
  207. {
  208.         return FPU_atan2(FPU_sqrt(1.0-x*x), x);
  209. }

  210. //反正切函数
  211. double FPU_atan(double x)
  212. {                     
  213.         return FPU_atan2(x,1.0f);
  214. }

  215. //双曲正弦函数
  216. double FPU_sinh(double x)
  217. {                     
  218.         return (FPU_exp(x)-FPU_exp(-x))/2;
  219. }

  220. //双曲余弦函数
  221. double FPU_cosh(double x)
  222. {                    
  223.         return (FPU_exp(x)+FPU_exp(-x))/2;
  224. }

  225. //双曲正切函数
  226. double FPU_tanh(double x)
  227. {                     
  228.         return (FPU_exp(x)-FPU_exp(-x))/(FPU_exp(x)+FPU_exp(-x));
  229. }

  230. //反双曲正弦函数
  231. double FPU_asinh(double x)
  232. {                     
  233.         return FPU_log(x+FPU_sqrt(x*x+1));
  234. }

  235. //反双曲余弦函数
  236. double FPU_acosh(double x)
  237. {                    
  238.         return FPU_log(x+FPU_sqrt(x*x-1));
  239. }

  240. //反双曲正切函数
  241. double FPU_atanh(double x)
  242. {                     
  243.         return FPU_log((1+x)/(1-x))/2;
  244. }

  245. //度转弧度
  246. double FPU_torad(double x)
  247. {
  248.         return x*FPU_PI/180;
  249. }

  250. //随机数函数
  251. double FPU_random(double x)
  252. {
  253.         return (x<2)?rand()%8192/8192.0:rand()%(int)(x);
  254. }
复制代码
发表于 2017-2-1 18:46:25 | 显示全部楼层
如果使用math.h
优化的时候启用SSE试试如何!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|批处理之家 ( 渝ICP备10000708号 )

GMT+8, 2026-3-16 23:45 , Processed in 0.009946 second(s), 8 queries , File On.

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表