## Java編程那些事兒7——進制的概念
作者:陳躍峰
出自:[http://blog.csdn.net/mailbomb](http://blog.csdn.net/mailbomb)
**1.2?進制的概念**
因為不可能為每個數值都創造一個符號,所以需要用基本數字組合出復合的數值,這樣就有了進制的概念。
其實所有進制都是人為的創造,都是用來計數方便的。現在最常用的進制是十進制,當然其它的進制也在使用中。例如“半斤八兩”這個成語,就反映了古代一斤等于十六兩的概念,也就是十六進制計數方式。
計算機編程中常用的進制有二進制、八進制、十進制和十六進制,十進制還是最主要的表達形式。在編程中,大家書寫的數值默認為十進制。
對于進制,有兩個最基本的概念:基數和運算規則。
**1.?基數**
基數指一種進制中組成的基本數字,也就是不能再拆分的數字。例如十進制是0-9,二進制是0和1,八進制是0-7,十六進制是0-9,A-F(大小寫均可)。或者可以簡單的這樣記憶,假設是n進制的話,基數就是[0,n-1]的數字,基數的個數和進制值相同,十進制有十個基數,依次類推。
**2.?運算規則**
運算規則就是進位或借位規則,這個類似于一般計算機書籍中位權的概念,例如對于十進制來說,該規則是“滿十進一,借一當十”,也就是低位的數字滿十了向高位進一,從高位借到的一,相當于低位上的十。其它的進制也是這樣,對于二進制來說,就是“滿二進一,借一當二”,八進制和十六進制也是這樣。
在數學上表示一個數字是幾進制,通常使用如下格式:[數值]進制數,例如[10]2 表示二進制數值10。
**1.2.1 二進制**
二進制是計算機內部數據表示的形式,所以學習計算機編程必須熟悉二進制。熟悉二進制有以下幾個用途:
**1.?更容易理解計算機的數據存儲方式**
計算機內部的很多轉換,例如數據類型之間的強轉,都可以用二進制解釋最終的結果的值。
**2.?二進制的運算速度高**
二進制的運算速度比十進制高的多。例如求2的n次方,通過移位實現的效率比數學方法高效。
**3.?使用二進制數值進行數據存儲**
以二進制的形式存儲數值,一個是比較節約資源,可以使用二進制的位來存儲信息,例如常見的硬件控制信息,都是二進制的形式進行提供的。
如前所述,二進制包含0和1兩個基數,運算規則是“滿二進一,借一當二”,下面簡單的介紹一下二進制的計數方式。
例如十進制的0-9用二進制進行表達,則依次是:
0,1,10,11,100,101,110,111,1000,1001
說明:數值之間使用逗號進行間隔。
下面是二進制的一些基本運算結果:
1.?加法運算
0 + 0 = 0
0 + 1 = 1
1 + 0 = 1
1 + 1 = 10
2.?減法
0 – 0 = 0
0 – 1 = -1
1 – 0 = 1
1 – 1 = 0
3.?乘法
0 × 0 = 0
0 × 1 = 0
1 × 0 = 0
1 × 1 = 1
4.?除法
0 / 0??? 無意義
0 / 1 = 0
1 / 0??? 無意義
1 / 1 = 1
以下是一些符合的表達式:
110 + 111 = 1101
這些基本的運算結構在實際開發中一般不會直接用到,但是通過這些內容可以加深對于二進制概念的理解。
**1.2.2 二進制和十進制之間的轉換**
由于計算機內部的數據是以二進制進行表達的,而十進制又是日常生活中最常用的進制,所以它們之間經常需要進行轉換。下面介紹一下轉換的方式。
**1.2.2.1 十進制轉換為二進制**
十進制整數轉換為二進制有三種方法,分別是除二取余、計算器轉換和經驗法。十進制小數的轉換方法最后做簡單的介紹。
1.除二取余法
除二取余法是轉換時的最基本方法,也是最通用的方法。規則為:使用十進制和2去除,取每次得到的商和余數,用商繼續和2相除,直到商為零為止,第一次得到的余數作為二進制的低位,最后一次得到的余數作為二進制的高位,由余數組成的數字就是轉換后二進制的值。例如十進制的13轉換為二進制的計算步驟如下:
商?????????? 余數
13?/?2?=?6??????????? 1
6?? /?2?=?3??????????? 0
3?? /?2?=?1??????????? 1
1?? /?2?=?0??????????? 1
則計算的最終結果就是1101。
2.計算器轉換
Windows操作系統中的計算器也可以很方便的實現進制之間的轉換。在程序菜單中附件子菜單中打開計算器,從打開的計算器的查看菜單中,選擇“科學型”,輸入你要轉換的十進制的數字,例如13,然后界面上數字顯示框西側的“二進制“,則轉換后的數值就直接顯示在計算器中。
3.經驗法
對于二進制熟悉以后,那么計算十進制對應的數字可以通過一些基本的數學變換來實現,在使用經驗法以前,必須熟記2的0-10次方對應的十進制的值,依次是:
1,2,4,8,16,32,64,128,256,512,1024
則轉換一些特殊的數字時可以極大的提高轉換速度,例如數字65,則可以這樣轉換:
65 = 64 + 1
64對應的二進制形式為1000000
1對應的二進制形式為1
則65的二進制形式為1000001
這個只適合轉換一些特殊的數字,適應性沒有除二取余法廣泛。
十進制小數的轉換采用的一般方法是乘二取整法,規則為:對于小數部分先乘二,然后獲得運算結果的整數部分,然后將結果中的小數部分再次乘二,直到小數部分為零為止,則把第一次得到的整數部分作為二進制小數的高位,后續的整數部分作為地位就是轉換后得到的二進制小數。需要說明的是,有些十進制小數無法準確的用二進制進行表達,所以轉換時符合一定的精度即可,這也是為什么計算機的浮點數運算不準確的原因。
例如0.25轉換為二進制小數的步驟如下:
整數部分
0.25 × 2 = 0.5????? 0
0.5?× 2 = 1.0????? 1
則0.25轉換為二進制小數為0.01
如果一個十進制數字既有整數部分,也有小數部分,則分開進行轉換即可。
**1.2.2.2 二進制轉換為十進制**
二進制轉換為十進制采用的方法是:數字乘位權相加法。下面先以十進制為例來說明該方法,例如十進制數字345的值,5的位權是1,4的位權是10,3的位權是100,則有如下表達式成立:?345=5 × 1 + 4 × 10 + 3 × 100,這就是數字乘位權相加法的原理。
其實對于十進制整數的位權很有規則,從右向左第n位的位權是十的(n-1)方,例如個位是10(1-1),十位是10(2-1),依次類推。那么二進制整數的位權規律和這個一致,也就是從右向左第n位的位權是二的(n-1)方。
例如二進制整數1011轉換為十進制的表達式為:
[1011]2 = 1 × 20 + 1 × 21 + 0 × 22 + 1 × 23 = 1 + 2 + 0 + 8=11
而對于二進制的小數,也是采用一樣的方法,只是二進制小數的位權規則為,小數點后第一位小數的位權是2的-1次方,第二位是2的-2次方,依次類推。
例如二進制小數0.1101轉換為十進制小數的表達式為
[0.1101]2=1 ×2-1 + 1 ×2-2 + 0 × 2-3 + 1 × 2-4 = 0.5 + 0.25 + 0 + 0.0625=0.8125
同理,如果二進制包含整數和小數部分,則分開進行轉換即可。
**1.2.3 二進制和八進制、十六進制之間的轉換**
雖然二進制是計算機內部的數據表達形式,但是由于二進制基數太少,則導致數字比較長,為了簡化數字的書寫,就創建了八進制和十六進制。八進制和十六進制就是對二進制的簡化,所以二進制到八進制和十六進制的轉換非常簡單。
二進制整數轉換為八進制的方法是“三位一并“,也就是從右側開始,每3位二進制數字轉換為八進制的一位,依次類推,因為二進制的三位數字可以表達的區間是000-111,剛好和0-7重合。例如:
二進制的10111轉換為8進制為:最后三位111轉換為7,前面的數字10轉換為2,則轉換后得到的八進制數字為27。
二進制整數轉換為十六進制的方法是“四位一并“,例如10111轉換為十六進制是0111轉換為7,1轉換為1,則轉換后得到的十六進制數字是17。
二進制小數轉換為八進制的方法也是“三位一并“,只是轉換時從小數的高位開始,也就是小數的左側開始。例如0.10111轉換為八進制是101轉換為5,110轉換為6,則轉換得到的八進制小數為0.56。需要特別注意的是,小數最后如果不足三位,一定要在后續補零以后再進行轉換。
二進制小數轉換為十六進制的方法也是“四位一并”,只是轉換時從小數的高位開始。例如二進制小數0.10111轉換為十六進制小數為,1011轉換為b,1000轉換為8,則轉換后得到的十六進制是0.b8。
如果二進制數包含整數和小數部分,則分開進行轉換。
- 前言
- (1)序言
- (2)程序設計是什么?
- (3)你適合學習程序設計嗎?
- (4)如何學好程序設計?
- (5)程序設計介紹小結
- (6)計算機軟件基本概念
- (7)進制的概念
- (8)計算機內部的數據表達
- (9)網絡編程基礎
- (10)Java語言簡介
- (11)JDK的獲得、安裝和配置
- (12)第一個HelloWorld程序
- (13)Eclipse基本使用
- (14)Eclipse基礎使用進階
- (15)如何學好Java語法
- (16)代碼框架、關鍵字和標識符
- (17)基本數據類型
- (18)變量和常量
- (19)數據類型轉換
- (20)空白、語句結束和注釋
- (21)算術運算符
- (22)比較運算符
- (23)邏輯運算符
- (24)賦值運算符
- (25)位運算符
- (26)移位運算符
- (27)其它運算符
- (28)運算符優先級
- (29)表達式
- (30)流程控制基礎
- (31)if語句語法(1)
- (32)if語句語法(2)
- (33)if語句語法(3)
- (34)switch語句語法
- (35)while語句語法
- (36)do-while語句語法
- (37)for語句語法
- (38)break和continue語句
- (39)流程控制綜合示例1
- (40)流程控制綜合示例2
- (41)流程控制綜合示例3
- (42)流程控制綜合練習
- (43)數組概述
- (44)數組基礎語法
- (45)數組使用示例1
- (46)數組使用示例2
- (47)數組使用示例3
- (48)多維數組基礎
- (49)多維數組使用示例1
- (50)多維數組使用示例2
- (51)多維數組練習
- (52)方法聲明
- (53)方法聲明示例
- (54)方法調用
- (55)方法重載和參數傳遞
- (56)方法練習
- (57)面向對象基礎
- (58)類(一)
- (59)類(二)
- (60)對象
- (61)面向對象設計方法和面向對象特性(一)
- (62)繼承(二)
- (63)多態性
- (64)訪問控制符、修飾符和其它關鍵字
- (65)static修飾符
- (66)final修飾符
- (67)this和super
- (68)抽象類和接口(一)
- (69)抽象類和接口(二)
- (70)抽象類和接口(三)
- (71)內部類簡介
- (72)包的概念
- (73)JDK文檔使用
- (74)java.lang包介紹1
- (75)String類使用
- (76)StringBuffer類和System類
- (77)包裝類
- (78)時間和日期處理
- (79)Random隨機處理
- (80)集合框架簡述
- (81)異常處理概述
- (82)異常處理語法1
- (83)異常處理語法2
- (84)IO簡介
- (85)IO類體系
- (86)文件操作之File類使用
- (87)文件操作之讀取文件
- (88)文件操作之寫文件
- (89)讀取控制臺輸入
- (90)裝飾流使用1
- (91)裝飾流使用2
- (92)IO使用注意問題
- (93)多線程基礎
- (94)多線程實現方式1
- (95)多線程實現方式2
- (96)多線程使用示例1
- (97)多線程使用示例2
- (98)多線程問題及處理1
- (99)多線程問題及處理2
- (100)多線程問題及處理3
- (101)網絡編程概述
- (102)網絡編程技術1
- (103)網絡編程技術2
- (104)網絡編程技術3
- (105)網絡編程技術4
- (106)網絡編程技術5
- (107)網絡協議概念
- (108)網絡編程示例1
- (109)網絡編程示例2
- (110)網絡編程小結