X/2和x>>1或x*2和x<<1的差異,其中x是整數 [英] Difference in x/2 and x>>1 or x*2 and x << 1 where x is an integer

查看:0
本文介紹了X/2和x>>1或x*2和x<<1的差異,其中x是整數的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!

問題描述

我們知道,要計算整數x/2,我們只需為x*2編寫類似的y=x/2;;但優秀的程序員使用位操作來計算這一點。

他們只是y = x >> 1;

這兩種方法有什么區別嗎? 我所說的差異是指所需時間/空間/內存的差異,或者兩者完全相同(即x/2由x>>1實現)?

與其他數字而不是2的乘除也是以相同的方式實現的(即5*5 = 10*2 + 5*1 = 10 << 1 + 5 = 25)?

推薦答案

這個問題已經在荒唐的魚兒博客上得到了回答: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代碼。下面的示例說明了Divide運算符的用途(始終來自同一文檔):

遺憾的是,您的優化不符合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 
", div8(x) );
    printf("rs : %d 
", 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  

401392行,有一條test指令,它將檢查奇偶校驗位,如果數字為負數,則在右移3個單位之前將1 << (n-1) = 7與x相加。

這篇關于X/2和x&gt;&gt;1或x*2和x&lt;&lt;1的差異,其中x是整數的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持IT屋!

查看全文
登錄 關閉
掃碼關注1秒登錄
發送“驗證碼”獲取 | 15天全站免登陸
全免费A级毛片免费看无码播放