x / 2和x >> 1或x * 2和x << 1的差,其中x是整数

用户名

众所周知,为了计算整数x / 2,我们y=x/2;对x * 2的写法与此类似;但是好的程序员会使用位操作来计算这一点。

他们只是做 y = x >> 1;

这两种方法之间有什么区别吗?差异是指所需的时间/空间/内存差异,或者两者完全相同(即x / 2由x >> 1实现)?

还有用其他数字而不是2进行乘法/除法的方式是否相同(即5*5 = 10*2 + 5*1 = 10 << 1 + 5 = 25)?

在ridiculousfishblog上已经回答了这个问题:http : //ridiculousfish.com/blog/posts/will-it-optimize.html

  1. 除以2至右移

GCC会将2的整数除法转换为右移吗?

int halve_it(int x) {
   return x / 2;
}

int halve_it(int x) {
   return x >> 1;
}

右移位运算符等效于向负无穷大舍入的除法,但正常除法向零舍入。因此,对于奇数负数,建议的优化将产生错误的结果。

可以通过在移位之前将最高有效位添加到分子上来“固定”结果,而gcc可以做到这一点。

优秀的程序员可以让编译器优化其代码,除非它们会降低性能。

编辑:由于您需要官方消息,所以我们引用C99的标准基本原理文档。您可以在这里找到它:http : //www.open-std.org/jtc1/sc22/wg14/www/docs/C99RationaleV5.10.pdf

在C89中,涉及负操作数的整数除法可以按实现定义的方式向上或向下取整;目的是避免在运行时代码中产生开销,以检查特殊情况并强制执行特定行为。但是,在Fortran中,结果将始终截断为零,并且数字编程社区似乎可以接受这种开销。因此,C99现在需要类似的行为,这应该有助于将代码从Fortran移植到C。本文档§7.20.6.2中的表说明了所需的语义。

您的优化在C89中应该是正确的,因为它可以让编译器按需进行。但是,C99引入了新的约定以符合Fortran代码。这是除法运算符的期望示例(始终来自同一文档):

在此处输入图片说明

不幸的是,您的优化不符合C99标准,因为对于x = -1,它不能给出正确的结果:

#include <stdio.h>

int div8(int x)
{
    return x/3;
}

int rs8( int x )
{
    return x >> 3;
}

int main(int argc, char *argv[])
{
    volatile int x = -1;
    printf("div : %d \n", div8(x) );
    printf("rs : %d \n", rs8(x) );

    return 0;
}

Result:
div : 0 
rs : -1 
[Finished in 0.2s]

如果看一下已编译的代码,您会发现一个有趣的区别(与g ++ v4.6.2一起编译):

0040138c <__Z4div8i>:
  40138c:   55                      push   %ebp
  40138d:   89 e5                   mov    %esp,%ebp
  40138f:   8b 45 08                mov    0x8(%ebp),%eax
  401392:   85 c0                   test   %eax,%eax
  401394:   79 03                   jns    401399 <__Z4div8i+0xd>
  401396:   83 c0 0f                add    $0x7,%eax
  401399:   c1 f8 04                sar    $0x3,%eax
  40139c:   5d                      pop    %ebp
  40139d:   c3                      ret    

0040139e <__Z3rs8i>:
  40139e:   55                      push   %ebp
  40139f:   89 e5                   mov    %esp,%ebp
  4013a1:   8b 45 08                mov    0x8(%ebp),%eax
  4013a4:   c1 f8 03                sar    $0x3,%eax
  4013a7:   5d                      pop    %ebp
  4013a8:   c3                      ret  

line上401392有一条test指令,该指令将检查奇偶校验位,如果数字为负,则将1 << (n-1) = 7在右移3个单位之前加到x上。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

x = x + 1!= x ++?

来自分类Dev

Slurm版本控制-2.X和1X

来自分类Dev

ldexp(1,x)和exp2(x)之间的差异

来自分类Dev

更改黑白ElasticSearch 1.x和2.x

来自分类Dev

“1 << x”和“pow(2, x)”有什么区别?

来自分类Dev

什么是(x&1)和(x >> = 1)?

来自分类Dev

获取设备图像比例(例如@ 1x,@ 2x和@ 3x)

来自分类Dev

添加没有 1x 版本的 @2x 和 @3x 图片

来自分类Dev

如何通过 x.Something1 和 x.Something2“查询语法”组“x”?

来自分类Dev

计算1 +1!/ X + 2!/ X ^ 2 +…+ N!/ X ^ N

来自分类Dev

在Haskell中计算`[[1,x ^ 1,x ^ 2,...,x ^ n]`

来自分类Dev

x = x + 1和x ++在实现上的差异

来自分类Dev

SSO FormsAuthentication - 2 个应用程序 - 1 x WebForms 和 1 x MVC

来自分类Dev

在Java中创建列表[xn,x-n + 1,...,x,x + 1,x + 2,... x + n]

来自分类Dev

关于 1x2 卷积和组合梯度

来自分类Dev

Tuple <X1,X2 ..>。Create和新的Tuple <X1,X2 ..>之间的优缺点是什么

来自分类Dev

编写查询以确定所有X1,X2,以使X1和X2的D值不同

来自分类Dev

Tuple <X1,X2 ..>。Create和新的Tuple <X1,X2 ..>之间的优点/缺点是什么

来自分类Dev

是否有关于x ^ a的x * log(x)的渐近极限,其中a为(1,2)?

来自分类Dev

#div1-x导致对#div2-x进行相应的操作,其中x = [az]

来自分类Dev

Handlebars 1.x和2.x API之间有什么区别?

来自分类Dev

在同一台计算机上运行1.x和2.x

来自分类Dev

用于x1 + x2 + ... + xn的解析器和扫描仪

来自分类Dev

2x“循环”和1x“直到”->无法运行宏

来自分类Dev

关闭GMS 2.x和GMS 1.x中的模式对话框?

来自分类Dev

2x8和1x16之间有区别吗?

来自分类Dev

将 x => array.Contains(x) 表达式转换为 x=> x == 1 || x==2

来自分类Dev

iOS中不同设备上的图像1x,2x和3x问题

来自分类Dev

为什么x in(1,2,3):比x == 1或x == 2或x == 3快?

Related 相关文章

  1. 1

    x = x + 1!= x ++?

  2. 2

    Slurm版本控制-2.X和1X

  3. 3

    ldexp(1,x)和exp2(x)之间的差异

  4. 4

    更改黑白ElasticSearch 1.x和2.x

  5. 5

    “1 << x”和“pow(2, x)”有什么区别?

  6. 6

    什么是(x&1)和(x >> = 1)?

  7. 7

    获取设备图像比例(例如@ 1x,@ 2x和@ 3x)

  8. 8

    添加没有 1x 版本的 @2x 和 @3x 图片

  9. 9

    如何通过 x.Something1 和 x.Something2“查询语法”组“x”?

  10. 10

    计算1 +1!/ X + 2!/ X ^ 2 +…+ N!/ X ^ N

  11. 11

    在Haskell中计算`[[1,x ^ 1,x ^ 2,...,x ^ n]`

  12. 12

    x = x + 1和x ++在实现上的差异

  13. 13

    SSO FormsAuthentication - 2 个应用程序 - 1 x WebForms 和 1 x MVC

  14. 14

    在Java中创建列表[xn,x-n + 1,...,x,x + 1,x + 2,... x + n]

  15. 15

    关于 1x2 卷积和组合梯度

  16. 16

    Tuple <X1,X2 ..>。Create和新的Tuple <X1,X2 ..>之间的优缺点是什么

  17. 17

    编写查询以确定所有X1,X2,以使X1和X2的D值不同

  18. 18

    Tuple <X1,X2 ..>。Create和新的Tuple <X1,X2 ..>之间的优点/缺点是什么

  19. 19

    是否有关于x ^ a的x * log(x)的渐近极限,其中a为(1,2)?

  20. 20

    #div1-x导致对#div2-x进行相应的操作,其中x = [az]

  21. 21

    Handlebars 1.x和2.x API之间有什么区别?

  22. 22

    在同一台计算机上运行1.x和2.x

  23. 23

    用于x1 + x2 + ... + xn的解析器和扫描仪

  24. 24

    2x“循环”和1x“直到”->无法运行宏

  25. 25

    关闭GMS 2.x和GMS 1.x中的模式对话框?

  26. 26

    2x8和1x16之间有区别吗?

  27. 27

    将 x => array.Contains(x) 表达式转换为 x=> x == 1 || x==2

  28. 28

    iOS中不同设备上的图像1x,2x和3x问题

  29. 29

    为什么x in(1,2,3):比x == 1或x == 2或x == 3快?

热门标签

归档