位運算處理2的n次方的除法

2021-09-29 12:46:34 字數 1659 閱讀 3444

假設x為乙個int型變數,請給出乙個用來計算x/

32的值的函式div32.要求不能使用除法、

乘法、模運算、比較運算、迴圈語句和條件語句。

可以使用右移、加法以及按位運算。

#include

using

namespace std;

void

div32

(int n)

intmain()

這裡注意,這個函式是設計用於整除

如果不是整除的話,結果按照c語言的整除規則——只保留整數部分

特別注意!!

要實現c語言的整除規則的話則引入乙個偏置常數是必要的!

不然如下:

#include

using

namespace std;

intmain()

執行結果:

-2請按任意鍵繼續. . .

當被除數是負數且不能整除時,就會出現錯誤

有人可能會想,加個 if 去判斷啊

但是,題目說了不能用條件語句!

所以,還是得引入偏置常數,下面具體來看看偏置常數是如何得來的

如果大家多測幾個資料,就會發現,如果直接進行位移操作,誤差只是1而已

這個「1」,其實可以看作是該數的機器碼向右位移後數值位的最後一位

-3的機器碼——1…1101

向右位移1位——1…110—— -2

要修復那個bug的話,只要設定好什麼條件下給數值位最後一位進一位就ok了

那麼究竟是什麼條件下呢?

其實,這個條件就是是否整除

下面拿除以4簡單分析一下

拿八位的機器碼來看

0000 0100 ——真值:4

大家可以發現,往1左邊走,分別是8, 16, 32 …

這些左邊的數字完全可以除以4,也就是說不會出現除不盡4的情況

主要是1右邊的數—— 2,1

舉個例子:

0000 0110—— 6 除不盡4

那麼,規律就已經出來了~

是否可以被4整除,就看4在機器碼中對應的數字右邊是否有值

若沒有,則可以整除

若有,則不能整除

現在看到剛剛給出的-3的例子

-3 的機器碼——1…101

除以2,則看2對應的數字——倒數第二位的右邊

有1——不能整除

則要在位移後加一

1…10+1 = 1…11

即為-1 ——加了1才是正確的

回到除以32的題目

int x=

(n>>31)

&0x1f

;//偏置常數

其實,這乙個偏置常數為什麼這麼設定的答案已經出來了

x=11111=31(n為負數)

x=00000=0(n為正數)

int ans=

(n+x)

>>

5;

可以發現,偏置常數11111則是機器碼的末尾5位——對應除數32

n+x——只要n機器碼的末尾5位中存在乙個1,則這個加法會實現前面提到的——「加一」

——在位移後數值位的最後一位加一

以上!解析完畢~

計算2的n次方

任意給定乙個正整數n n 100 計算2的n次方的值。輸入乙個正整數n。輸出2的n次方的值。計算2的n次方也是依次相乘2,大於個位則進製,從後向前儲存元素,所以要令初始值為1.includeint main 建立儲存資料的陣列 a 49 1 用陣列儲存 int n int i int x 0 x代表...

計算2的N次方

總時間限制 1000ms 記憶體限制 65536kb 描述任意給定乙個正整數n n 100 計算2的n次方的值。輸入輸入乙個正整數n。輸出輸出2的n次方的值。樣例輸入 5樣例輸出 32提示高精度計算 1 include 2 int main int argc,char ar 3 表示大整數,低位在前...

21 03 02 高精度運算 以2的n次方為例

1 include 2 3using namespace std 45 const int n 3010 定義乙個3010位的陣列,表示高精度運算的支援位數,最大可以很大67 intmain 8 10 11重點!在高精度運算的加,減,乘中,儲存數字的時候是翻轉的,0位存的是最高位,第3009位存的是...