浮点数有没有左移右移的操作?有意义吗?

冰与火 2012-10-25 06:06:00
如题。浮点数有没有快速的乘2幂除2幂的操作?
...全文
7084 13 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
sunjiaqi2004 2013-02-27
  • 打赏
  • 举报
回复
引用 8 楼 baichi4141 的回复:
左移右移是位操作,不是数学运算 整数左移右移可以当做是乘2除2,但仅仅是“可以当做”,左移右移运算符不是为了让你写数学式更难看而存在的 乘2除2就直接写*/,用什么左移右移啊,除了增加代码难看程度之外没有任何意义 顺便,任何一个好一点的编译器,都能做到优化数学运算,整数的乘2除2几乎可以肯定优化成左移右移(乘5直接优化成一次移2位和一次加法),浮点数也可能优化成……
讲的太好了,我上次有在书上看到,有些编译器遇到2的指数乘除时自动应运移位运算的,所以程序员无需移位、
newtee 2012-10-25
  • 打赏
  • 举报
回复 1
[Quote=引用 1 楼 的回复:]

浮点数的移位没有意义,因为它的bits都有特殊含义,移位则直接改变本质了。
[/Quote]++
mLee79 2012-10-25
  • 打赏
  • 举报
回复
编译器不好做这些优化吧, 它又不知道数据的范围, 如果数据是 NAN , INF , 那乘除都应该没影响, 如果是下溢的非规格化数, 乘以2就可能变成规格化数, 动作就大了, 对很小的一个规格化数, 除以2就可能变成非规格化数, 这些特例太多了, 如果都考虑到, 那还不如普通的乘除快了..
并且x86机器有协处理器,有SSE指令, 浮点运算本来就不比整数运算慢多少, 没必要搞这些..
如果是在些 ARM 啊啥的机器上, 你自己又知道数据的范围不大, 怎么弄都不会出现 NAN INF 非规格化数, 这样搞搞倒是可能提高点性能...
yisikaipu 2012-10-25
  • 打赏
  • 举报
回复
好奇地看了一下,VS2008编译器的优化只是把 f*2 变成 f+f,呵呵

而浮点运算器内部对此有没有优化呢?
lin5161678 2012-10-25
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 的回复:]
左移右移是位操作,不是数学运算
整数左移右移可以当做是乘2除2,但仅仅是“可以当做”,左移右移运算符不是为了让你写数学式更难看而存在的
乘2除2就直接写*/,用什么左移右移啊,除了增加代码难看程度之外没有任何意义

顺便,任何一个好一点的编译器,都能做到优化数学运算,整数的乘2除2几乎可以肯定优化成左移右移(乘5直接优化成一次移2位和一次加法),浮点数也可能优化成指数位增减,这都是编译器的……
[/Quote]
如果是在写编译器 那就是另一回事了
baichi4141 2012-10-25
  • 打赏
  • 举报
回复
左移右移是位操作,不是数学运算
整数左移右移可以当做是乘2除2,但仅仅是“可以当做”,左移右移运算符不是为了让你写数学式更难看而存在的
乘2除2就直接写*/,用什么左移右移啊,除了增加代码难看程度之外没有任何意义

顺便,任何一个好一点的编译器,都能做到优化数学运算,整数的乘2除2几乎可以肯定优化成左移右移(乘5直接优化成一次移2位和一次加法),浮点数也可能优化成指数位增减,这都是编译器的工作范畴,用不着你操心,不允许你操心
写代码姑且不论正确性和功能效率,单单论写法,第一优先的就是可读性,所谓“提高效率”的那点小技巧,在编译器优化面前不值一提
mLee79 2012-10-25
  • 打赏
  • 举报
回复
就像这个样子:

#include <stdio.h>

float fltShift( float x , int n )
{
int ix = *(int*)&x;
ix += n * 0x00800000;
return *(float*)&ix;
}

double dblShift( double x , int n )
{
long long llx = *(long long*)&x;
llx += n * 0x0010000000000000LL;
return *(double*)&llx;
}

int main()
{
printf( "%f\n" , fltShift( 123.456f , -3 ) );
printf( "%f\n" , fltShift( 123.456f , -2 ) );
printf( "%f\n" , fltShift( 123.456f , -1 ) );
printf( "%f\n" , fltShift( 123.456f , 0 ) );
printf( "%f\n" , fltShift( 123.456f , 1 ) );
printf( "%f\n" , fltShift( 123.456f , 2 ) );
printf( "%f\n" , fltShift( 123.456f , 3 ) );

printf( "%f\n" , dblShift( 123.456 , -3 ) );
printf( "%f\n" , dblShift( 123.456 , -2 ) );
printf( "%f\n" , dblShift( 123.456 , -1 ) );
printf( "%f\n" , dblShift( 123.456 , 0 ) );
printf( "%f\n" , dblShift( 123.456 , 1 ) );
printf( "%f\n" , dblShift( 123.456 , 2 ) );
printf( "%f\n" , dblShift( 123.456 , 3 ) );

return 0;
}


mLee79 2012-10-25
  • 打赏
  • 举报
回复
错了, 32位该是 bits * 0x00800000 ...
mLee79 2012-10-25
  • 打赏
  • 举报
回复
如果忽略特殊的数 NaN (阶码全1,尾数非0), INF (阶码全1,尾数0) , 非规格化的数 (阶码0,尾数非0, 尾数无隐含的1), 可以用阶码加减1做乘除2运算, 如果考虑到这些特殊情况, 还是直接用浮点吧...

32位浮点就加减 bits * 0x08000000 , 64位浮点就加减 bits * 0x0010 0000 0000 0000 ....
冰与火 2012-10-25
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 的回复:]

浮点数*2只要指数部分+1就行,感觉会很快
没研究过浮点数乘除法
[/Quote]有具体的做法吗?
majia2011 2012-10-25
  • 打赏
  • 举报
回复
精度问题
dpdp_2012 2012-10-25
  • 打赏
  • 举报
回复
浮点数*2只要指数部分+1就行,感觉会很快
没研究过浮点数乘除法
图灵狗 2012-10-25
  • 打赏
  • 举报
回复
浮点数的移位没有意义,因为它的bits都有特殊含义,移位则直接改变本质了。

65,186

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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