如何判斷整型算數運算是否溢位

2021-08-07 23:50:19 字數 1343 閱讀 5456

乙個算術運算溢位,是指完整的整數結果不能放到資料型別的字長限制中去。

溢位的原因是顯而易見的,考慮兩個非負整數x和y,滿足0<=x,y<=(2^w)-1。xy可以被表示為w位無符號數字,然而考慮它們的和的話,我們可以得到0<=x+y<=2^(w+1)-2。這個和需要w+1位來表示。如果我們再用其他數加上這個結果的話,可能我們又將需要w+2,w+3位來表示新的結果。這種持續的「字長膨脹「意味著,如果想要完整地表示算數運算的結果,我們就不能對字長做任何限制(實際上lisp就是這樣幹的)。如果我們限制了資料型別的字長,溢位的發生是不可避免的。

由於溢位後的結果往往不是我們想要的結果,我們必須對溢位時的情形另做處理,但在此之前我們必須得先能夠判斷什麼時候發生了溢位。

無符號整數的溢位判斷比較簡單:對乙個字長w的無符號數加法運算,當x+y>=2^w時,第w+1位被程式捨去,相當於在x+y的和的基礎上減去了2^w。由於x,y<=(2^w)-1,所以有x+y

int

uadd_ok(unsigned x,unsigned y)

有符號整型數加法的溢位判斷稍微麻煩一些:我們把可能發生的溢位情況分為正溢位與負溢位,正溢位是指兩個非負數相加卻得負數的情況,而負溢位是指兩個負數相加卻得正數的情況。可以證明其他時候都沒有發生溢位。

int tadd_ok(int x,int

y)

一種常見的錯誤的判斷方法如下:

int tadd_ok(int x,int

y)

實際上不論是否溢位,(x+y)-x始終得到y,(x+y)-y始終得到x。至於為什麼(x+y)-x始終得到y,講得學術一點是因為補碼加上形成乙個阿貝爾群,由阿貝爾群的交換律和結合律有(x+y)-x==y。(其實只要想到從補碼加上來理解+-運算,會很自然地理解為什麼不能這樣判斷)。

能夠判斷整數加法是否溢位後,我們再來看看如何判斷如何判斷整數減法溢位,一種很自然的做法是:

int tsub_ok(int x,int

y)

咋一看好像也沒有什麼不對的,但在寫**時用到負號來取相反數時一定要注意對tmin的處理,因為-tmin=tmin(tmin沒有對應的正數),在這個函式中如果不對tmin做處理的話,如果y取tmin那麼對任意x<0函式都會判斷發生溢位(其實並沒有)。

對於tmin的處理很簡單,考慮y==tmin的情況下x取何值時x-y會溢位呢,只有x>=0的時候。

改善過後的函式:

int tsub_ok(int x,int

y)

關於tmin的值可由標頭檔案中int_min巨集定義獲得。

最後我們討論一下如何判斷整數乘法發生溢位,判斷溢位的**如下:

int tmult_ok(int x,int

y)

判斷無符號整型和有符號整型

在計算機記憶體裡,整數以補碼形式儲存 正數的補碼即原碼 正數如 50000 原碼為 0000 0000 0000 0000 1100 0011 0101 0000 補碼為 0000 0000 0000 0000 1100 0011 0101 0000 負數如 100 原碼為 1000 0000 00...

python 整型類似的bool判斷

import commands status,output commands.getstatusoutput ansible 10.1.193.6 m shell a df m 測試status print status status 0 print status status 1 print ty...

號碼運商判斷

public class operatorutils return true 判斷運營商 public static string execute string phone else if phone.startswith 86 去除 86後 號碼應為11位 if phone.length 11 判...