整数、浮点数在计算机中的存储,-128二进制怎么表示,
目錄
- 1 計算機底層存儲數據的基本原理
- 2 整數的存儲
- 2.1 整數的基本概念
- 2.2 整數的編碼方式
- -128的二進制表示
- 3浮點數存儲
- 3.1 二進制十進制間小數怎么轉換
1 計算機底層存儲數據的基本原理
????????計算機要處理的信息是多種多樣的,如數字、文字、符號、圖形、音頻、視頻等,這些信息在人們的眼里是不同的。但對于計算機來說,它們在內存中都是一樣的,都是以二進制的形式來表示。要想學習編程,就必須了解二進制,它是計算機處理數據的基礎。
????????內存條是一個非常精密的部件,包含了上億個電子元器件,它們很小,達到了納米級別。這些元器件,實際上就是電路;電路的電壓會變化,要么是 0V,要么是 5V,只有這兩種電壓。5V 是通電,用1來表示,0V 是斷電,用0來表示。所以,一個元器件有2種狀態,0 或者 1。我們通過電路來控制這些元器件的通斷電,會得到很多0、1的組合。例如,8個元器件有 28=256 種不同的組合,16個元器件有 216=65536 種不同的組合。雖然一個元器件只能表示2個數值,但是多個結合起來就可以表示很多數值了。
????????我們可以給每一種組合賦予特定的含義,例如,可以分別用 1101000、00011100、11111111、00000000、01010101、10101010 來表示 C、語、言、中、文、網 這幾個字,那么結合起來 1101000 00011100 11111111 00000000 01010101 10101010 就表示”C語言中文網“。一般情況下我們不一個一個的使用元器件,而是將8個元器件看做一個單位,即使表示很小的數,例如 1,也需要8個,也就是 00000001。1個元器件稱為1比特(Bit)或1位,8個元器件稱為1字節(Byte),那么16個元器件就是2Byte,32個就是4Byte,以此類推。我們平時使用計算機時,通常只會設計到 KB、MB、GB、TB 這幾個單位,PB 和 EB 這兩個高級單位一般在大數據處理過程中才會用到。
- 1Byte = 8 Bit
- 1KB = 1024Byte = 2^10Byte
- 1MB = 1024KB = 2^20Byte
- 1GB = 1024MB = 2^30Byte
- 1TB = 1024GB = 2^40Byte
- 1PB = 1024TB = 2^50Byte
- 1EB = 1024PB = 2^60Byte
????????所以,在內存中沒有abc這樣的字符,也沒有gif、jpg這樣的圖片,只有0和1兩個數字,計算機也只認識0和1。所以,計算機使用二進制,而不是我們熟悉的十進制,寫入內存中的數據,都會被轉換成0和1的組合。
2 整數的存儲
2.1 整數的基本概念
????????大家知道,整數包括負數,零,和正數。計算機中的整數分為有符號數和無符號數。
- 有符號數:最高位表示符號,即最高位為0,表示正數,最高位為1,表示負數。如果用N位來表示整數,那么有符號數的范圍為:[-2(N-1),(2(N-1))-1]。用8位來表示有符號整數數,由于第8位用于表示了符號,因此,整數的表示范圍為[-128,+127]。
- 無符號數:表示非負數,整個位數都用來表示整數的值。如果用N位來表示整數,無符號數的表示范圍為[0,(2^N)-1]。用8位來表示有符號整數數,則無符號數的表示范圍為[0,255]。
2.2 整數的編碼方式
整數的編碼分為原碼、反碼、和補碼。計算里使用的是補碼的存儲方式。它們的定義如下:
- 原碼:在數值前面增加了一位符號位(即最高位為符號位),該位為0表示正數,該位為1表示負數,其余位表示數值的大小。
- 反碼:正數的反碼與其原碼相同。負數的反碼是對其原碼逐位取反,但符號位除外。
- 補碼:正數的補碼與其原碼相同,負數的補碼就是對該負數的反碼加1。
-128的二進制表示
今天看到8位2進制表示的范圍是-128-127。原來沒有想過為什么是這個范圍,仔細一想,奇怪呀,-128是怎么表示的。127是0111 1111,而-128為什么是1000 0000呢,這不是-0嗎?于是就有了下文要說的一些內容。
STEP1
為了從根本上明白-128為什么是1000 0000,我們需要從一個叫【模】的東西講起,并且把你原來關于原碼補碼反碼的一些東西都暫時忘掉。
‘模’是什么,簡單來講就是一個范圍內的極限。舉一個經典的例子,我們日常生活中的12個刻度的時鐘,它表示0-12小時。假設它現在處于2的位置,如果你要讓它減少4個小時,到10的位置,你會怎么做?把時鐘順時鐘按照3,4,5的方向轉8個小時?還是按照1,12,11的方向逆時針轉動轉4個小時?這2者的結果都是一樣的,讓時鐘到了10的位置。
我們來看一下,一個是撥了8小時,一個是撥了4小時,8+4=12,12-8=4。一個時鐘一圈12個小時,也就是說最大的表示上限是12。往前8小時和往后12-8=4小時效果是一樣的。而這個12就是所謂的【模】。在模的范圍內, +某個數X 與 +模-|x| 的效果是一樣的。舉個例子
十進制的數,20 和 80 ,兩者相加是100,100為模,那么我們50-20 =30,與50+80=130,如果去除百位上的數字,在模(100)的范圍內,是不是都是30,結果相同。也就是X -Y = X+(模-|Y|)。
沒錯吧。不過上面我們是 大-小,如果是 小-大呢?怎么表示。
STEP2
還是20這個數字,按照原來是思路10-20=-10,10+(100-20)=90,不相等了對吧,這可怎么辦?我們偉大的前人想到了一個辦法,將負數用它的絕對值的補數表示也就是“模-|負數x|” 表示。也就是【模】-|負數|,100-|-10|=90;這樣是不是就很完美了,可以表示負數了!
不過這里還存在一個問題,既然-10可以用90表示了,那么原本的90該怎么表示呢?很直接,模范圍內一分為二,0-49表示正數,50-99表示負數。
STEP3
好了,回到-128上。對于8進制的2進制數,模是2的八次,256。如果拋開負數,我們能表示0 ~ 255沒問題吧。現在我們把0 ~ 255進行對半分,0 ~ 127以及128 ~ 255.像上面所說的100一樣,,0 ~ 127表示正數,128 ~ 255表示負數補數的負值,也就是說128 ~ 255為【模】-|負數x|后的值,256-|-128|=128,256-|-1|=255。到這里你應該明白為什么八位2進制數能夠表示的范圍是-128 ~ 127了吧。 需要注意的是,以上這些運算都需要在-128~127的范圍內,這里所謂的負數的二進制碼就是它們的補碼,不然會產生溢出,也就不符合這個邏輯了。
接下來我們再看看為什么-128的表示是1000 0000。我們是用256-|-128|=128去表示-128的,128的補碼就是1000 0000,這也就是為什么-128是用1000 0000表示了。
最后說一下計算機是怎么求這個補碼的。負數在計算機中都是用補碼存儲表示的,當我們輸入一個負數的時候,計算機還是要用 模-絕對值來求對應的補碼,可是計算機只有加法,為了求這個對應的補碼,計算機會將原碼首位不變,其余位取反然后加1來求這個補碼,-128沒有原碼和反碼,只有補碼。換個角度考慮,負數的補碼就是其絕對值源碼+1,-128就是128的原碼10000000求反0111 1111 +1 -》1000 0000
因為計算機是以補碼來存儲整數的,所以補碼就顯得很重要。那么如何計算整數的補碼呢?下面以具體例子來說明。
100 的補碼:01100100
0 的補碼:0
-100 的補碼:絕對值:01100100 -->取反加1:10011011+1 -->10011100
1 的補碼:00000001
-1 的補碼:絕對值:00000001 -->取反加1:111111110+1 -->11111111
127 的補碼:01111111
-128 的補碼:絕對值:10000000 -->取反加1:01111111+1 -->10000000 在計算機系統中,數值一律用補碼來表示(存儲)。
從定義可以看出,正數的補碼,反碼,原碼相同。0的補碼就是本身。那么負數的原碼和補碼如何轉換呢?==已知一個負數求補碼方法:絕對值原碼按位求反加1。已知負數補碼求負數方法:符號位不變,其他位按位求反加1。==對于8位整數來說,補碼的表示范圍為[-128,127]。 大家應該記住一些常見的補碼的表示,這些數包括但不局限于下面表中列出的數:
3浮點數存儲
一般的編程語言都是將浮點類型的數據采用單精度類型( float)和雙精度類型(double)來存儲,float 數據占用 32bit,double 數據占用 64bit,我們在聲明一個變量 float f= 2.25f; 的時候,是如何分配內存的呢?如果胡亂分配,那世界豈不是亂套了么,其實不論是 float 還是 double 在存儲方式上都是遵從 IEEE 的規范的, float 遵從的是 IEEE R32.24 ,而 double 遵從的是 R64.53。無論是單精度還是雙精度在存儲中都分為三個部分:
- 浮點數表示的數值:V = (-1)^s × M × 2^E
- 符號(sign) :1個bit表示,當s=0,V為正數;當s=1,V為負數。
- 階碼(exponent) :E的作用是對浮點數加權,用于存儲科學計數法中的指數數據,并且采用移位存儲。float類型的階碼是 8 bits,double類型的階碼是 11 bits。
- 尾數(significand) :M是一個二進制小數,因為是二進制,所以科學計數法中這個值范圍是:1≤M<2。(和十進制中范圍為1~10一樣)
R32.24 和 R64.53 的存儲方式都是用科學計數法來存儲數據的。比如 8.25 用十進制的科學計數法表示就為:8.2510^1 ,而 120.5 可以表示為:1.205*10^2 ,這些小學的知識就不用多說了吧。而我們的傻蛋計算機根本不認識十進制的數據,他只認識 0, 1,所以在計算機存儲中,首先要將上面的數更改為二進制的科學計數法表示, 8.25 用二進制表示可表示為 1000.01,
3.1 二進制十進制間小數怎么轉換
十轉二
十進制的小數轉換為二進制,主要是小數部分乘以2,取整數部分依次從左往右放在小數點后,直至小數點后為0。例如十進制的0.125,要轉換為二進制的小數。
轉換為二進制,將小數部分0.125乘以2,得0.25,然后取整數部分0
再將小數部分0.25乘以2,得0.5,然后取整數部分0
再將小數部分0.5乘以2,得1,然后取整數部分1
則得到的二進制的結果就是0.001
二轉十
二進制的小數轉換為十進制主要是乘以2的負次方,從小數點后開始,依次乘以2的負一次方,2的負二次方,2的負三次方等。例如二進制數0.001轉換為十進制。
第一位為0,則0*1/2,即0乘以2負 一次方。
第二位為0,則0*1/4,即0乘以2的負二次方。
第三位為1,則1*1/8,即1乘以2的負三次方。
各個位上乘完之后,相加,01/2+01/4+1*1/8得十進制的0.125
因此 120.5 用二進制表示為:1110110.1 用二進制的科學計數法表示 1000.01 可以表示為 1.0001* 2^3,1110110.1可以表示為 1.1101101* 2^6。
IEEE 754對有效數字M和指數E,還有一些特別規定。前面說過,1≤M<2,也就是說,M可以寫成1.xxxxxx的形式,其中xxxxxx表示小數部分。IEEE 754規定,在計算機內部保存 M時,默認這個數的第一位總是1,因此可以被舍去,只保存后面的xxxxxx部分。比如保存1.01的時候,只保存01,等到讀取的時候,再把第一位的1加上去。這樣做的目的,是節省1位有效數字。以32位float浮點數為例,留給M只有23位,將第一位的1舍去以后,等于可以保存24位有效數字。 道理就是在這里,那 24bit 能精確到小數點后幾位呢,我們知道 9 的二進制表示為 1001,所以 4bit 能精確十進制中的 1 位小數點,== 24bit 就能使 float 能精確到小數點后 6 位。 ==
至于指數E,情況就比較復雜。 首先,E為一個無符號整數(unsigned int)這意味著,如果E為8位 (float類型) ,它的取值范圍為0~255;如果E為11位(double類型),它的取值范圍 為0~2047。但是,我們知道,科學計數法中的E是可以出現負數的(因為0.75用科學計數法表示就是1.1*2^-1),所以IEEE 754規定,存入內存時E的真實值必須再加上一個中間數,==對于8位的E,這個中間數是127;對于11位的E,這個中間數是1023。==比如,2^10的E是10,所以保存成32位浮點數時,必須保存成10+127=137,即10001001。
接下來我們看下 8.25用float類型存儲的數據到底是什么樣的?8.25f用二進制的科學計數法表示為:1.0001*2^3,按照上面的存儲方式,符號位s = 0,表示為正;指數位 E = 3+127=130 ,尾數部分為1.0001,去掉最前面的整數1,就是M = 0001,所以8.25f用float類型在內存中存儲的格式就是:
參考自:
https://www.cnblogs.com/mukekeheart/p/10517298.html
https://blog.csdn.net/u010867670/article/details/88869042
https://jingyan.baidu.com/article/425e69e6e93ca9be15fc1626.html
總結
以上是生活随笔為你收集整理的整数、浮点数在计算机中的存储,-128二进制怎么表示,的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 原创:全球文科衰落,学文真的没有出路吗?
- 下一篇: 原创:深圳老牌民办校“搬家合并”风波又起