Board logo

标题: 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源码。仅单一头文件,方便调用。
  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. }
复制代码

作者: B魔方大人    时间: 2017-2-1 18:46

如果使用math.h
优化的时候启用SSE试试如何!




欢迎光临 批处理之家 (http://bbs.bathome.net/) Powered by Discuz! 7.2