# 數(shù)據(jù)存儲和進制轉化
標簽(空格分隔): 基礎知識
---
傳統(tǒng)的計算機都是基于馮諾依曼體系,用集成電路中二極管的通電和斷電,高電平和低電平等狀態(tài)位來表示1和0(就這么個意思,簡要描述錯誤之處請指出),故計算機只能識別二進制的0、1。現(xiàn)實世界的數(shù)據(jù)都是通過一定的規(guī)則轉化為二進制數(shù)據(jù)流然后才能在計算機中存儲和運算.
1.進制的概念: 進制也就是進位制,是人們規(guī)定的一種進位方法涮雷。 對于任何一種進制---X進制,就表示某屏幕快照 2016-12-23 下午2.10.18一位置上的數(shù)運算時是逢X進一位。 十進制是逢十進一掂咒,十六進制是逢十六進一,二進制就是逢二進一
在采用進位計數(shù)的數(shù)字系統(tǒng)中阱当,如果只用r個基本符號表示數(shù)值俏扩,則稱為r進制(Radix-r Number System),r稱為該數(shù)制的基數(shù)(Radix)弊添。不同的數(shù)制的共同特點如下:
(1)录淡、每一種數(shù)制都有篤定的符號集。例如油坝,十進制數(shù)制的基本符號有十個:0嫉戚,1,2澈圈。彬檀。。瞬女,9窍帝。二進制數(shù)制的基本符號有兩個:0和1.
2、每一種數(shù)制都使用位置表示法诽偷。即處于不同位置的數(shù)符所代表的值不同坤学,與它所在位的權值有關疯坤。
例如:十進制1234.55可表示為
1234.55=1×10^3+2×10^2+3×10^1+4×10^0+5×10^(-1)+5×10^(-2)
可以看出,各種進位計數(shù)制中權的值恰好是基礎的某次冪深浮。因此压怠,對任何一種進位計數(shù)制表示的數(shù)都可以寫成按權展開的多項式。
3. 八進制和十六進制
人類一般的思維方式是十進制,編碼人員看到一堆0 1的二進制數(shù)肯定蛋疼,例如一個最簡單char 類型字符 a的二進制表示: 0010 0110,直接用十進制又無法準確計算機思維方式(二進制 0B).所以出現(xiàn)了八進制和十六進制,當然十六進制的運用更加廣泛,例如一個int型的32位數(shù)字,用八進制表示 32/3 = 2,余2也就是說我們每個前面要加2個0.學過編程的肯定知道變量的地址一般都是用十六進制表示 :
printf(" c address : %p\n",&c);
輸出: c address : 0x7fff5fbff73c
所以說用十六進制表達二進制字符串無疑是最佳的方式飞苇,這就是八進制和十六進制出現(xiàn)的原因菌瘫。
4.進制間的轉換
常用的進制有 二進制 八進制 十進制 十六進制
- 1.二進制,八進制,十六進制 -> 十進制
都是按權展開多項式相加得到十進制
示例:
二進制1010.101 ->? 1 * 2^3 + 0 * 2^2 + 1 * 2^1 + 0 * 2^0 + 1*2^(-1) + 0 * 2^(-2) + 1*2^-3=10.6875
八進制? 13.1到十進制 1*8^1 + 3*8^0 + 1*8^(-1) = 11.125
十六進制13.1到十進制 1*16^1 + 3*16^0 + 1*16^(-1) = 19.0625
- 2.十進制 -> 二進制 八進制 十六進制? 都是按照整數(shù)部分除以基數(shù)(r)取余,小數(shù)部分乘以基數(shù)(r)取整.
十進制10.25 到二進制
10/2 --0
5/2? --1
2/2? --0
1/2? --1
0.25 * 2 = 0.5 --? 0
0.5 * 2? = 1? ? --? 1
整數(shù)部分: 1010
小數(shù)部分: 01
所以到二進制 1010.01,
同理八進制和十六進制,只是基數(shù)改變而已
- 3 二進制 <----> 八進制 十六進制
二進制轉化為八進制: 從小數(shù)點起,二進制每三個數(shù)字分為一組,若不夠小數(shù)點前面的在每組前面加0,后面的在每組后面就0,然后把每組數(shù)轉化為相應的十進制數(shù)就可以了
10010101.101 - (010 010 101) . (101) = (2 2 5) . (5) = 225.5
八進制轉二進制:? ? 八進制數(shù)每一位轉化為二進制數(shù),拼起來
257.56 = (10 101 111). (101 110) = 10101111.101110
二進制轉十六進制: 小數(shù)點起,二進制數(shù)每4個二進制位分為一組,如果不夠小數(shù)點前面的在每組前面加0,后面的在每組后面加0,然后把每組數(shù)轉化為相應的十進制數(shù)就行,注意一點就是
10->A , 11->B , 12->C , 13->D , 14->E, 15->F 大于等于10的用字母表示(不區(qū)分大小寫)
10101111.10111? -> (1010 1111).(1011 1000) = (12 16).(13 9) = AF.B8
數(shù)據(jù)的分類
編程中數(shù)據(jù)類型一般分為基本數(shù)據(jù)類型和復合數(shù)據(jù)類型,特別是面向對象編程中的類和對象就是一種典型的復合數(shù)據(jù)類型.本質上復合數(shù)據(jù)類型也是由基本數(shù)據(jù)類型構成.
以C語言為例,基本數(shù)據(jù)類型有 字符型char, 整型(無符號 帶符號 長 短整型等等),實現(xiàn)(float,double),bool型(其實bool型也是整型,只不過用宏定義聲明了而已)
先說基本數(shù)據(jù)類型
1.無符號
unsigned int b = 1; //
printf(" c address : %#x\n",b);
輸出 : 0x7b (0x1)
可以看出直接就是二進制數(shù)表示的
2.帶符號
對于帶符號整數(shù),最高位是符號位.0代表+,1代表-
int c = -1;
printf(" c address : %#x\n",c);
輸出: 0xffffffff (11111111111111111111111111111111)
輸出和無符號完全不一樣,這是因為帶符號整型和無符號整型的二進制表示方式不一樣
這又涉及到另外一個問題,原碼,反碼和補碼
- 1.原碼:
數(shù)值X的原碼記做[X]原,若果機器字長為n(即用n個二進制位表示數(shù)據(jù)).最高位符號位,其余的n-1表示數(shù)值的絕對值, 數(shù)值0的原碼有兩種表示方式: [+0]原 = 0000 0000 , [-0]原 = 1000 0000
例子: 字長n為8的數(shù)字
[+1] = 0000 0001? ? ? ? ? [-1] = 1000 0001
[+127] = 0111 111? ? ? ? ? [-127] = 1111 1111
兩者相加明顯有問題,這又引出了下一個問題-反碼
- 2.反碼
數(shù)值X的反碼記做[X]反,最高位是符號位,0為正1為負.正數(shù):反碼=原碼,負數(shù): 反碼=原碼絕對值按位取反,數(shù)值0的反碼有兩種表示方式 [+0] = 0000 0000, [-0] = 1111 1111,
例子: 字長n為8的數(shù)字
[+1] = 0000 0001? ? ? ? ? ? [-1] = 1111 1110
[+127] = 0111 1111? ? ? ? ? [-127] = 1000 0000
用反碼進行計算? ? 1111 1110 -> 1000 0001
-1 + 1 =? 0? |? ? (1111 1110)反 + (0000 0001)?反 = (1000 0000)原=? 0沒有問題
1+(-2)=-1? |? ? (0000 0001)反 + (1111 1101)反 = (1000 0001)原 = -1 沒有問題
-1 + 2 = 1? |? ? (1111 1110)反 + (0000 0010)反 = (0000 0000)原 = 0? 發(fā)生了溢出
所以反碼也是不對的,這就又引出了補碼這個概念
- 3.補碼
數(shù)值X的補碼記做[X]補,如果數(shù)字字長為n,最高位為符號位,0代表正好,1代表負號.正數(shù)的補碼和原碼反碼都相同,負數(shù)的補碼等于反碼在末尾加1.數(shù)值0有唯一的補碼 [+0] = 0000 0000 [-0] = 0000 0000
例子: 字長n=8的數(shù)字
[+1]補 = 0000 0001? ? ? ? ? [-1]補 = 1111 1111
[+127]補 = 0111 1111? ? ? ? [-127]補 = 1000 0001
[+45]補=0010 1101? ? ? ? ? [-45]補=1101 0011
反碼的運算:
-1 + 1 = 0? ? ? ? (1111 1111)補 + (0000 0001)補 = (0000 0000)補 = (0000 0000)原 沒有問題
-2 + 1 = -1? ? ? (1111 1110)補 +? (0000 0001補 = (1111 1111)補 = (1000 0001)原 沒有問題
-1 + 2 = 1? ? ? ? (1111 1111)補 + (0000 0010)補 = (0000 0001)補 = (0000 0001)原
沒有問題
- 浮點數(shù)的存儲
根據(jù)IEEE754標準,任意一個浮點數(shù)V可以表示為以下形式
如十進制V = 9.0,表示為二進制 1001.0,相當于 1.001 * 2^3, 則 S = 0, M=1.001,E = 3;
同理十進制V = -9.0,表示為二進制 -1001.0*2^3,則S = 1,M=1.001,E=3;
參考:
http://blog.csdn.net/lonelyroamer/article/details/7670869
http://www.ruanyifeng.com/blog/2010/06/ieee_floating-point_representation.html