对于c语言int类型和float,以及double类型表示范围的计算
首先說一下我原來錯誤的認(rèn)識
int是32個bit,
如果我們把第一位理解為符號位,那么很顯然int的范圍是-(2^31-1)~2^31-1
但是實際上我們都知道int的最小值是-2^31次。。
為什么會這樣呢。。首先對于這個問題困惑的話說明你的邏輯不夠強
因為如果第一位是符號位那么上面的分析必然是正確的。。而且按照上面的表示方法,我們顯然可以發(fā)現(xiàn)
有兩個零,一個是+0,一個是-0
然而實際上好像并沒有這么一說
所以說。。從這里。。正常的邏輯思維應(yīng)該得出一個結(jié)論。。那就是c語言的int表示方法并不是我們想的那樣
那么我們用x表示一個值。。+,-符號來表示正負(fù)號,等號右側(cè)用來表示這個數(shù)在計算機里存儲的值。。我們都知道計算機是沒法存儲正負(fù)號的(硬件)(額似乎不太恰當(dāng))
那么根據(jù)int的表示方法的hash他是怎么工作的呢
+x=x
-x=~(x)+1
除了要注意按位取反表達(dá)式。。我們還要注意需要把規(guī)定位數(shù)的兩個數(shù)每一位對齊。。高位和過低都截斷(?)
那么這樣我們就可以發(fā)現(xiàn)。。-(2^31)=~(2^31)+1
這個太長啦。。我們舉一個短一點的例子來算一下
-(2^3)=~(2^3)+1=2^3
-1000=0111+1=1000
哇哦好神奇。。這個就是4位數(shù)能表示的最小負(fù)數(shù)。。4位可以表示的最小負(fù)數(shù)可以用2^3來表示
那么同理。。32位整數(shù)能表示的最小負(fù)數(shù)就可以用2^31來表示。。顯然可以存下的啊
所以說經(jīng)過計算我們就發(fā)現(xiàn)了。。int的范圍是-(2^31)~(2^31-1)
===========================================================================
研究完了int我們再來研究一下浮點數(shù)
那么我們來研究一下float的表示方法
此時我們是按照IEEE754標(biāo)準(zhǔn)來定義存在計算機里面浮點數(shù)的數(shù)據(jù)結(jié)構(gòu)
那么對于float來講。。它是一個32位浮點數(shù)
我們按照最低位是第0位來講
首先這個32bit的位串要分成三部分。。符號位。。階碼。。尾數(shù)
我解釋一下啥叫符號位。。第31位是符號位,0:+,1:-
啥是階碼呢。。。階碼是用來表示這個
1.xxx*2^x的x的大小的。。
首先這個標(biāo)準(zhǔn)規(guī)定了都用這種方式來表示浮點數(shù)
1.0是最小的。。1+1-2^(-23)是最大的基數(shù)。。(前面那個我都管它叫基數(shù))
我用10進(jìn)制的小數(shù)舉個例子。。比如說。。3位小數(shù)的最大值是多少呢。。
顯然我們知道是0.999那么其實它等于1-10^(0-3)
那么同理我們可以知道23位尾數(shù)的的小數(shù)的二進(jìn)制最大小數(shù)可以表示成1-(2^(0-23))
然后我們就知道了。。那我這個x要有正有負(fù)才可以就是說。。小數(shù)點兩個方向都可以浮動
但是他的這個存的策略是。。我只存正數(shù)。。等到我要取出來計算并且表示的時候
我用一個偏移量把它拆成兩半。。一半大于零。。一半小于零
那么實際上對于float的這個尾數(shù)的存儲策略的話。。是沒有用到狀態(tài)壓縮的。。
它的尾數(shù)是多少我們就存多少。。如實復(fù)制即可
=================
那么對于浮點數(shù)這個東西我們還要注意
你怎么表示零。。
出現(xiàn)了1/非常小但不為零的小數(shù)=》無窮 你怎么處理
首先對于零的問題。。你尾數(shù)域默認(rèn)最高有效位是1...所以沒有存它。。
但是既然最高有效位不為0.。你怎么表示真正的0呢
所以這時候他們的策略是犧牲狀態(tài)空間來特判表示0
那么對于無窮的情況呢?同理。。特判
當(dāng)階碼全為零,尾數(shù)也全為零表示的真值是真正的0,并不是用很小的數(shù)逼近
當(dāng)階碼全為1,尾數(shù)全為零表示的是無窮
根據(jù)符號位有,+0,-0,正無窮和負(fù)無窮
對于階碼全為1,尾數(shù)不為零的情況。。我們表示的是一個NaN非數(shù),表示運算無效
====================
知道了上面這些我們就可以來計算float類型的值的范圍了。。
由于這里的表示方法正數(shù)和負(fù)數(shù)只差一個符號
所以我們只考慮它的絕對值的范圍就好了
即1.xxxx*2^x
那么我們知道階碼不存負(fù)數(shù)。。
所以上面那個x并不等于階碼的大小。。而是等于階碼E-127
為什么呢。。
我們知道E用8個bit存。。那么最大表示11111111=2^8-1
也就是255,那么我們知道這個數(shù)被用來特判無窮大和NaN
最小是0,用來特判0
所以對于除此之外的數(shù)。。
我們可以用1~254。。
但是你要有正有負(fù)啊。。分成兩半。。
都減去127就變成了-126~127
這樣就變成了x的范圍
知道了1.xxx的范圍和2^x的范圍。。計算就很輕松了。。
絕對值
最大是(1+1-(2^(-23)))*2^127
最小是1.0*2^(-126)?
那么再具體的話。。加上正負(fù)號就行了。。
轉(zhuǎn)載于:https://www.cnblogs.com/linkzijun/p/6151418.html
總結(jié)
以上是生活随笔為你收集整理的对于c语言int类型和float,以及double类型表示范围的计算的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: nyoj 55 懒省事的小明
- 下一篇: 2.8加密工具与散列