浮点乘法如何优化,希望能是位运算

素衣白马客京华 2014-01-10 02:43:54
在单片机中需要用到浮点乘法,具体是
double x;
x = x*0.01
乘0.01能否优化成位运算呢
...全文
723 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
「已注销」 2014-01-13
  • 打赏
  • 举报
回复
用定点数运算代替浮点数运算。
赵4老师 2014-01-10
  • 打赏
  • 举报
回复
80x87浮点协处理器的功能早八辈子就集成到CPU内部了!
========== 浮点运算指令集 ======================================================
---------- 一、控制指令(带9B的控制指令前缀F变为FN时浮点不检查,机器码去掉9B)----
FINIT                 初始化浮点部件                   机器码  9B DB E3
FCLEX                 清除异常                         机器码  9B DB E2
FDISI                 浮点检查禁止中断                 机器码  9B DB E1
FENI                  浮点检查禁止中断二               机器码  9B DB E0
WAIT                  同步CPU和FPU                     机器码  9B
FWAIT                 同步CPU和FPU                     机器码  D9 D0
FNOP                  无操作                           机器码  DA E9
FXCH                  交换ST(0)和ST(1)                 机器码  D9 C9
FXCH ST(i)            交换ST(0)和ST(i)                 机器码  D9 C1iii
FSTSW ax              状态字到ax                       机器码  9B DF E0
FSTSW   word ptr mem  状态字到mem                      机器码  9B DD mm111mmm
FLDCW   word ptr mem  mem到状态字                      机器码  D9 mm101mmm
FSTCW   word ptr mem  控制字到mem                      机器码  9B D9 mm111mmm

FLDENV  word ptr mem  mem到全环境                      机器码  D9 mm100mmm
FSTENV  word ptr mem  全环境到mem                      机器码  9B D9 mm110mmm
FRSTOR  word ptr mem  mem到FPU状态                     机器码  DD mm100mmm
FSAVE   word ptr mem  FPU状态到mem                     机器码  9B DD mm110mmm

FFREE ST(i)           标志ST(i)未使用                  机器码  DD C0iii
FDECSTP               减少栈指针1->0 2->1              机器码  D9 F6
FINCSTP               增加栈指针0->1 1->2              机器码  D9 F7
FSETPM                浮点设置保护                     机器码  DB E4
---------- 二、数据传送指令 ----------------------------------------------------
FLDZ                  将0.0装入ST(0)                   机器码  D9 EE
FLD1                  将1.0装入ST(0)                   机器码  D9 E8
FLDPI                 将π装入ST(0)                    机器码  D9 EB
FLDL2T                将ln10/ln2装入ST(0)              机器码  D9 E9
FLDL2E                将1/ln2装入ST(0)                 机器码  D9 EA
FLDLG2                将ln2/ln10装入ST(0)              机器码  D9 EC
FLDLN2                将ln2装入ST(0)                   机器码  D9 ED

FLD    real4 ptr mem  装入mem的单精度浮点数            机器码  D9 mm000mmm
FLD    real8 ptr mem  装入mem的双精度浮点数            机器码  DD mm000mmm
FLD   real10 ptr mem  装入mem的十字节浮点数            机器码  DB mm101mmm

FILD    word ptr mem  装入mem的二字节整数              机器码  DF mm000mmm
FILD   dword ptr mem  装入mem的四字节整数              机器码  DB mm000mmm
FILD   qword ptr mem  装入mem的八字节整数              机器码  DF mm101mmm

FBLD   tbyte ptr mem  装入mem的十字节BCD数             机器码  DF mm100mmm

FST    real4 ptr mem  保存单精度浮点数到mem            机器码  D9 mm010mmm
FST    real8 ptr mem  保存双精度浮点数到mem            机器码  DD mm010mmm

FIST    word ptr mem  保存二字节整数到mem              机器码  DF mm010mmm
FIST   dword ptr mem  保存四字节整数到mem              机器码  DB mm010mmm

FSTP   real4 ptr mem  保存单精度浮点数到mem并出栈      机器码  D9 mm011mmm
FSTP   real8 ptr mem  保存双精度浮点数到mem并出栈      机器码  DD mm011mmm
FSTP  real10 ptr mem  保存十字节浮点数到mem并出栈      机器码  DB mm111mmm

FISTP   word ptr mem  保存二字节整数到mem并出栈        机器码  DF mm011mmm
FISTP  dword ptr mem  保存四字节整数到mem并出栈        机器码  DB mm011mmm
FISTP  qword ptr mem  保存八字节整数到mem并出栈        机器码  DF mm111mmm

FBSTP  tbyte ptr mem  保存十字节BCD数到mem并出栈       机器码  DF mm110mmm

FCMOVB                ST(0),ST(i) <时传送              机器码  DA C0iii
FCMOVBE               ST(0),ST(i) <=时传送             机器码  DA D0iii
FCMOVE                ST(0),ST(i) =时传送              机器码  DA C1iii
FCMOVNB               ST(0),ST(i) >=时传送             机器码  DB C0iii
FCMOVNBE              ST(0),ST(i) >时传送              机器码  DB D0iii
FCMOVNE               ST(0),ST(i) !=时传送             机器码  DB C1iii
FCMOVNU               ST(0),ST(i) 有序时传送           机器码  DB D1iii
FCMOVU                ST(0),ST(i) 无序时传送           机器码  DA D1iii
---------- 三、比较指令 --------------------------------------------------------
FCOM                  ST(0)-ST(1)                      机器码  D8 D1
FCOMI                 ST(0),ST(i)  ST(0)-ST(1)         机器码  DB F0iii
FCOMIP                ST(0),ST(i)  ST(0)-ST(1)并出栈   机器码  DF F0iii
FCOM   real4 ptr mem  ST(0)-实数mem                    机器码  D8 mm010mmm
FCOM   real8 ptr mem  ST(0)-实数mem                    机器码  DC mm010mmm

FICOM   word ptr mem  ST(0)-整数mem                    机器码  DE mm010mmm
FICOM  dword ptr mem  ST(0)-整数mem                    机器码  DA mm010mmm
FICOMP  word ptr mem  ST(0)-整数mem并出栈              机器码  DE mm011mmm
FICOMP dword ptr mem  ST(0)-整数mem并出栈              机器码  DA mm011mmm

FTST                  ST(0)-0                          机器码  D9 E4
FUCOM  ST(i)          ST(0)-ST(i)                      机器码  DD E0iii
FUCOMP ST(i)          ST(0)-ST(i)并出栈                机器码  DD E1iii
FUCOMPP               ST(0)-ST(1)并二次出栈            机器码  DA E9
FXAM                  ST(0)规格类型                    机器码  D9 E5
---------- 四、运算指令 --------------------------------------------------------
FADD                  把目的操作数 (直接接在指令后的变量或堆栈缓存器) 与来源操作数 (接在目的操作数后的变量或堆栈缓存器) 相加,并将结果存入目的操作数
FADDP  ST(i),ST       这个指令是使目的操作数加上 ST 缓存器,并弹出 ST 缓存器,而目的操作数必须是堆栈缓存器的其中之一,最后不管目的操作数为何,经弹出一次后,目的操作数会变成上一个堆栈缓存器了
FIADD                 FIADD 是把 ST 加上来源操作数,然后再存入 ST 缓存器,来源操作数必须是字组整数或短整数形态的变数

FSUB                  减
FSUBP
FSUBR                 减数与被减数互换
FSUBRP
FISUB
FISUBR

FMUL                  乘
FMULP
FIMUL

FDIV                  除
FDIVP
FDIVR
FDIVRP
FIDIV
FIDIVR

FCHS                  改变 ST 的正负值

FABS                  把 ST 之值取出,取其绝对值后再存回去。

FSQRT                 将 ST 之值取出,开根号后再存回去。

FSCALE                这个指令是计算 ST*2^ST(1)之值,再把结果存入 ST 里而 ST(1) 之值不变。ST(1) 必须是在 -32768 到 32768 (-215 到 215 )之间的整数,如果超过这个范围计算结果无法确定,如果不是整数 ST(1) 会先向零舍入成整数再计算。所以为安全起见,最好是由字组整数载入到 ST(1) 里。

FRNDINT               这个指令是把 ST 的数值舍入成整数,FPU 提供四种舍入方式,由 FPU 的控制字组(control word)中的 RC 两个位决定
                          RC    舍入控制
                          00    四舍五入
                          01    向负无限大舍入
                          10    向正无限大舍入
                          11    向零舍去
================================================================================
vipcxj 2014-01-10
  • 打赏
  • 举报
回复
对于0.01不可能优化,因为就算是浮点也是以二进制的科学计数发存放的。但换句话说,对于XXX*(2^n)是可以优化的,这里的n可以是负数,比如XXX*0.5 具体怎么优化,LZ去查下浮点在内存里是怎么放的吧,我记得有符号位,尾数和幂,不过都是二进制的
lm_whales 2014-01-10
  • 打赏
  • 举报
回复
如果又浮点库,直接使用 没有,定义定点数,表示浮点数, 或者自己定义浮点类型(进行简单的计算,根据需要够用就成)。
还有多远 2014-01-10
  • 打赏
  • 举报
回复
引用 2 楼 judwenwen2009 的回复:
[quote=引用 1 楼 uuuououlcz 的回复:] 位运算是针对整数的吧,浮点数位运算还木有见过......话说单片机浮点数用double了,float经度已经不够用了吗?
源数据是double的,理论上对特定的浮点运算是优化的,毕竟所有运算本质都是通过二进制实现的啊,我见过用为位运算实现开方运算的,比库函数快好几倍。所以想找找乘法的优化[/quote] 好吧,去搜了一下移位的开方算法,虽然不懂,但还真是涨姿势了,关于你说的浮点除法,看看这个有木有些用处: http://wenku.baidu.com/view/2f0f70d180eb6294dd886c1a.html
  • 打赏
  • 举报
回复
引用 1 楼 uuuououlcz 的回复:
位运算是针对整数的吧,浮点数位运算还木有见过......话说单片机浮点数用double了,float经度已经不够用了吗?
源数据是double的,理论上对特定的浮点运算是优化的,毕竟所有运算本质都是通过二进制实现的啊,我见过用为位运算实现开方运算的,比库函数快好几倍。所以想找找乘法的优化
还有多远 2014-01-10
  • 打赏
  • 举报
回复
位运算是针对整数的吧,浮点数位运算还木有见过......话说单片机浮点数用double了,float经度已经不够用了吗?

69,373

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧