是否可以使用>>
和<<
向左和向右移动,而不是使用*
和/
进行转换?
对于8位:0x01 * 2 = 0000 | 0010。
答案 0 :(得分:17)
当然(对于整数数学)你可以使用左乘两个乘以左移,并且右移乘二乘。
你不应该这样做。
有完美的左移和右移操作员,他们“完全按照他们对锡的说法”。为什么要混淆你的编译器或其他读取代码的人呢?
答案 1 :(得分:9)
你可以,但你为什么要这样做?转换操作是CPU可以做得最快的事情之一。
实际上,相反的情况经常被建议作为性能优化:使用移位来实现2次方的乘法/除法。
但是任何一个不太合适的编译器都会为你做到这一点,所以你绝对不应该手动执行:保持代码清晰是最重要的事情,所以如果你正在进行数学运算,请使用乘法和除法,并使用位移如果你在操纵比特。
答案 2 :(得分:8)
除非进行位操作,否则应避免在所有情况下进行移位。写作&lt;&lt;而不是* 2使代码不太清晰。除非你明确想要,否则不要使用位移。
编译器无论如何都会将*2
n 优化为<<
。
答案 3 :(得分:5)
你可以,但是将它优化为实际位移是一个聪明的编译器!另外,如果你的意思是“转移”,你最好写&lt;&lt;。当你的意思是'乘法'时,写下*。
请注意,浮点数根本不会改变:它们的指数只会增长。
答案 4 :(得分:3)
是的,除了一个问题:在处理负数时,除法可能以不同的方式正确转移。负数的右移行为是编译器定义的。
您当然可以使用无符号整数来避免此问题。
正如其他人所说,无论你使用移位还是乘法/除法,现代编译器都可能产生相同的输出。因此,使用任何使代码更容易遵循和维护的东西。
答案 5 :(得分:1)
是的,你可以。举个例子:
int main() {
if ((1*2) == (1 << 1)) printf("you certainly can!\n");
else printf("doesn't work that way\n");
}
它产生的输出:
you certainly can!
请参阅此回复的评论,了解为什么我们同意(0x01 * 2 == 0000 | 0010)比((1 * 2)==(1&lt;&lt; 1))更多问题,更简洁的版本。
答案 6 :(得分:1)
你可以,
x << 1 == x * 2
x << 2 == x * 4
etc...
and conversly
x >> 1 == x / 2
x >> 2 == x / 4
etc...
虽然我认为有经验的c程序员应该能够看到一点点转换操作,并且知道这两种方法是类似的。鉴于选择,我总是会使用位移,因为很清楚你的意图是什么。如果你确实使用了乘法/或除法选项,你显然需要评论为什么你突然将值乘以看似随机的数字。然而,位移明确表明您正在尝试移位。
至于任何optamization评论,除非绝对必要,例如时间关键的emebedded编程,我不会过分担心你的代码的optamization。代码可读性和可维护性应该是您的重点,而不是optamization!如果在开发结束时,您需要更多的性能,您可以随时返回并进行optamization(确保您非常谨慎地记录您所做的一切!)。但在开发过程中,我会选择最容易阅读和维护的内容,例如:使用'&lt;&lt;&lt; /'&gt;&gt;'。
答案 7 :(得分:0)
所有其他人都表示完全有可能这样做。这也毫无意义。如果你的意思是转移然后转移。如果你的意思是乘以然后乘以。不要将代码的读者与无用的“优化”混淆。
除问题外:
您的编译器将查看任何整数乘法/除以常量,并将表达式几乎一直减少到一系列移位/加法运算。这样做是因为二进制乘法并不是一项容易的任务,并且它比移位和加法需要更长的时间,一旦它们传入ALU,就可以在一个单一的时钟周期内完成。有趣的是CPU中的整数乘数大致相似但是以自动方式 - 使用单独的移位/添加操作仍然稍微快一些,因为您不需要停止并测试您正在进行的每个级别的转换的条件。
我可以为你起草这个基本算法,但它已经快到午夜所以你可以谷歌了。如果有足够的电话,我会编辑帖子并明天把它放进去。
这种优化尤其适用于乘以2 ^ n变量的常数,因为它是单个移位操作。
答案 8 :(得分:0)
是的你总能用2次乘法的力量代替换档,但正如已经指出的那样,为什么呢?没有指出的是,用移位替换乘法有时是有用的,而不仅仅是2的简单幂。例如,在320 * 200像素缓冲区的好日子里,像素字节的偏移是y * 320 + X。这可以按如下方式完成:
int OffsetXY( int x, int y)
{
int offset;
y <<= 6;
offset = y;
offset += y << 2; // offset = original y * 320
return offset + x;
}
虽然现在大多数开发人员只是学术兴趣,但它在嵌入式世界中很有用(最近在DS上做了一些编码,这种事情很有用)。