編寫函式tsub_ok的**,引數是x和y,執行的運算是x-y,如果計算x-y不產生溢位,函式就返回1.假設你寫的**如下:
int
tsub_ok
(int x,
int y)
此函式能檢測到兩個數相加,若發生溢位,則返回0,否則返回1。int
tadd_ok
(int x,
int y)
如果y的值為int_min(−231
−231
),那麼-y則應為2312
31,但實際效果是-y還是−231
−231
。這樣就會造成程式錯誤。
因為這裡發生了正溢位。可以從兩種角度進行解釋:
給出一些常識,int是4個位元組的,所以一共有32位二進位制。
1)補碼截斷。
初始時y為int_min(−231
−231
)。
補碼的值
1000 0000
0000 0000
0000 0000
0000 0000
對應權值−2
31−23
1………
…左邊是高有效位,右邊是低有效位。標紅色的為補碼的符號位。
取反後-y為2312
31
補碼的值
…0000 0000
1000 0000
0000 0000
0000 0000
0000 0000
對應權值……
23123
1 ………
…取反32位二進位制無法表示2312
31了,所以得拓展成更多位了,注意多了多少位已經不重要了,重要的是,現在的第32位已經不是符號位了,所以第32位的權值則為2312
31而不是負的了。
但最終變數是int型的,所以必須截斷。
補碼的值
1000 0000
0000 0000
0000 0000
0000 0000
對應權值−2
31−23
1………
…所以,最終-y的值為−231
−231
。2)溢位時運算。
一般來說,正溢位時,則可以認為運算結果得到了第33位二進位制的權值2322
32。所以就應該是:
初始時,y為−231
−231
。取反後,-y為2312
31。因為正溢位,所以減去2322
32,-y為2312
31-23223
2,最終為−231
−231
。
#include
#include
"stdafx.h"
#include
using
namespace std;
inttadd_ok
(int x,
int y)
inttsub_ok
(int x,
int y)
深入理解計算機系統 練習題2 32 答案與分析
錯誤示例 include include stdafx.h include using namespace std int tadd ok int x,int y int tsub ok int x,int y int main 列印結果 此問題的原因在於當y int min時,y y,為什麼y y...
《深入理解計算機系統》 練習題2 36答案
注意z1變數,是先進行型別轉換,然後再執行乘法,再會隱式地將y進行型別轉換,再繼續執行乘法。z2,z3變數都是一回事。注意z4變數,x y 這裡還是int型的,所以這裡正溢位,進行截斷,還是 2147483648。然後進行型別轉換,即進行位拓展,新拓展的位上的值都為1。此函式為初始版本,是用除法來檢...
深入理解計算機系統 練習題2 11 答案與分析
可執行 include include stdafx.h include using namespace std void inplace swap int x,int y void reverse array int a,int cnt int main int len sizeof a size...