假設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位存的是...