美国信息交换标准代码
( American Standard Code for Information Interchange, ASCII )
在计算机中,所有的数据在存储和运算时都要使用二进制数表示(因为计算机用高电平和低电平分别表示1和0),例如,象a、b、c、d这样的52个字母(包括大写)、以及0、1、2等数字还有一些常用的符号(例如*、#、@等)在计算机中存储时也要使用二进制数来表示,而具体用哪些二进制数字表示哪个符号,当然每个人都可以约定自己的一套(这就叫编码),而大家如果要想互相通信而不造成混乱,那么大家就必须使用相同的编码规则,于是美国有关的标准化组织就出台了所谓的ASCII编码,统一规定了上述常用符号用哪些二进制数来表示。
美国标准信息交换代码是由美国国家标准学会(American National Standard Institute , ANSI )制定的,标准的单字节字符编码方案,用于基于文本的数据。起始于50年代后期,在1967年定案。它最初是美国国家标准,供不同计算机在相互通信时用作共同遵守的西文字符编码标准,它已被国际标准化组织(International Organization for Standardization, ISO)定为国际标准,称为ISO 646标准。适用于所有拉丁文字字母。
ASCII 码使用指定的 7 位或 8 位二进制数组合来表示 128 或 256 种可能的字符。标准 ASCII 码也叫基础ASCII码,使用 7 位二进制数来表示所有的大写和小写字母,数字 0 到 9、标点符号, 以及在美式英语中使用的特殊控制字符。其中:
0~31及127(共33个)是控制字符或通信专用字符(其余为可显示字符),如控制符:LF(换行)、CR(回车)、FF(换页)、DEL(删除)、BS(退格)、BEL(振铃)等;通信专用字符:SOH(文头)、EOT(文尾)、ACK(确认)等;ASCII值为 8、9、10 和 13 分别转换为退格、制表、换行和回车字符。它们并没有特定的图形显示,但会依不同的应用程序,而对文本显示有不同的影响。
32~126(共95个)是字符(32sp是空格),其中48~57为0到9十个阿拉伯数字;
65~90为26个大写英文字母,97~122号为26个小写英文字母,其余为一些标点符号、运算符号等。
同时还要注意,在标准ASCII中,其最高位(b7)用作奇偶校验位。所谓奇偶校验,是指在代码传送过程中用来检验是否出现错误的一种方法,一般分奇校验和偶校验两种。奇校验规定:正确的代码一个字节中1的个数必须是奇数,若非奇数,则在最高位b7添1;偶校验规定:正确的代码一个字节中1的个数必须是偶数,若非偶数,则在最高位b7添1。
后128个称为扩展ASCII码,目前许多基于x86的系统都支持使用扩展(或“高”)ASCII。扩展 ASCII 码允许将每个字符的第 8 位用于确定附加的 128 个特殊符号字符、外来语字母和图形符号。以下为标准ASCII表:
Bin | Dec | Hex | 缩写/字符 | 解释 |
00000000 | 0 | 00 | NUL(null) | 空字符 |
00000001 | 1 | 01 | SOH(start of handling) | 标题开始 |
00000010 | 2 | 02 | STX (start of text) | 正文开始 |
00000011 | 3 | 03 | ETX (end of text) | 正文结束 |
00000100 | 4 | 04 | EOT (end of transm-ission) | 传输结束 |
00000101 | 5 | 05 | ENQ (enquiry) | 请求 |
00000110 | 6 | 06 | ACK (acknow-ledge) | 收到通知 |
00000111 | 7 | 07 | BEL (bell) | 响铃 |
00001000 | 8 | 08 | BS (backsp-ace) | 退格 |
00001001 | 9 | 09 | HT (horizon-tal tab) | 水平制表符 |
00001010 | 10 | 0A | LF (NL line feed, new line) | 换行键 |
00001011 | 11 | 0B | VT (vertical tab) | 垂直制表符 |
00001100 | 12 | 0C | FF (NP form feed, new page) | 换页键 |
00001101 | 13 | 0D | CR (carriage return) | 回车键 |
00001110 | 14 | 0E | SO (shift out) | 不用切换 |
00001111 | 15 | 0F | SI (shift in) | 启用切换 |
00010000 | 16 | 10 | DLE (data link escape) | 数据链路转义 |
00010001 | 17 | 11 | DC1 (device control 1) | 设备控制1 |
00010010 | 18 | 12 | DC2 (device control 2) | 设备控制2 |
00010011 | 19 | 13 | DC3 (device control 3) | 设备控制3 |
00010100 | 20 | 14 | DC4 (device control 4) | 设备控制4 |
00010101 | 21 | 15 | NAK (negati-ve acknowl-edge) | 拒绝接收 |
00010110 | 22 | 16 | SYN (synchr-onous idle) | 同步空闲 |
00010111 | 23 | 17 | ETB (end of trans. block) | 传输块结束 |
00011000 | 24 | 18 | CAN (cancel) | 取消 |
00011001 | 25 | 19 | EM (end of medium) | 介质中断 |
00011010 | 26 | 1A | SUB (substit-ute) | 替补 |
00011011 | 27 | 1B | ESC (escape) | 溢出 |
00011100 | 28 | 1C | FS (file separat-or) | 文件分割符 |
00011101 | 29 | 1D | GS (group separat-or) | 分组符 |
00011110 | 30 | 1E | RS (record separat-or) | 记录分离符 |
00011111 | 31 | 1F | US (unit separat-or) | 单元分隔符 |
00100000 | 32 | 20 | 空格 | |
00100001 | 33 | 21 | ! | |
00100010 | 34 | 22 | " | |
00100011 | 35 | 23 | # | |
00100100 | 36 | 24 | $ | |
00100101 | 37 | 25 | % | |
00100110 | 38 | 26 | & | |
00100111 | 39 | 27 | ' | |
00101000 | 40 | 28 | ( | |
00101001 | 41 | 29 | ) | |
00101010 | 42 | 2A | * | |
00101011 | 43 | 2B | + | |
00101100 | 44 | 2C | , | |
00101101 | 45 | 2D | - | |
00101110 | 46 | 2E | . | |
00101111 | 47 | 2F | / | |
00110000 | 48 | 30 | 0 |
00110001 | 49 | 31 | 1 | |
00110010 | 50 | 32 | 2 | |
00110011 | 51 | 33 | 3 | |
00110100 | 52 | 34 | 4 | |
00110101 | 53 | 35 | 5 | |
00110110 | 54 | 36 | 6 | |
00110111 | 55 | 37 | 7 | |
00111000 | 56 | 38 | 8 | |
00111001 | 57 | 39 | 9 | |
00111010 | 58 | 3A | : | |
00111011 | 59 | 3B | ; | |
00111100 | 60 | 3C | < | |
00111101 | 61 | 3D | = | |
00111110 | 62 | 3E | > | |
00111111 | 63 | 3F | ? | |
01000000 | 64 | 40 | @ | |
01000001 | 65 | 41 | A | |
01000010 | 66 | 42 | B | |
01000011 | 67 | 43 | C | |
01000100 | 68 | 44 | D | |
01000101 | 69 | 45 | E | |
01000110 | 70 | 46 | F | |
01000111 | 71 | 47 | G | |
01001000 | 72 | 48 | H | |
01001001 | 73 | 49 | I | |
01001010 | 74 | 4A | J | |
01001011 | 75 | 4B | K | |
01001100 | 76 | 4C | L | |
01001101 | 77 | 4D | M | |
01001110 | 78 | 4E | N | |
01001111 | 79 | 4F | O | |
01010000 | 80 | 50 | P | |
01010001 | 81 | 51 | Q | |
01010010 | 82 | 52 | R | |
01010011 | 83 | 53 | S | |
01010100 | 84 | 54 | T | |
01010101 | 85 | 55 | U | |
01010110 | 86 | 56 | V | |
01010111 | 87 | 57 | W | |
01011000 | 88 | 58 | X | |
01011001 | 89 | 59 | Y | |
01011010 | 90 | 5A | Z | |
01011011 | 91 | 5B | [ | |
01011100 | 92 | 5C | / | |
01011101 | 93 | 5D | ] | |
01011110 | 94 | 5E | ^ | |
01011111 | 95 | 5F | _ | |
01100000 | 96 | 60 | ` | |
01100001 | 97 | 61 | a | |
01100010 | 98 | 62 | b |
续表
01100011 | 99 | 63 | c | |
01100100 | 100 | 64 | d | |
01100101 | 101 | 65 | e | |
01100110 | 102 | 66 | f | |
01100111 | 103 | 67 | g | |
01101000 | 104 | 68 | h | |
01101001 | 105 | 69 | i | |
01101010 | 106 | 6A | j | |
01101011 | 107 | 6B | k | |
01101100 | 108 | 6C | l | |
01101101 | 109 | 6D | m | |
01101110 | 110 | 6E | n | |
01101111 | 111 | 6F | o | |
01110000 | 112 | 70 | p | |
01110001 | 113 | 71 | q | |
01110010 | 114 | 72 | r | |
01110011 | 115 | 73 | s | |
01110100 | 116 | 74 | t | |
01110101 | 117 | 75 | u | |
01110110 | 118 | 76 | v | |
01110111 | 119 | 77 | w | |
01111000 | 120 | 78 | x | |
01111001 | 121 | 79 | y | |
01111010 | 122 | 7A | z | |
01111011 | 123 | 7B | { | |
01111100 | 124 | 7C | | | |
01111101 | 125 | 7D | } | |
01111110 | 126 | 7E | ~ | |
01111111 | 127 | 7F | DEL (delete) | 删除 |
常见ASCII码的大小规则:0~9<A~Z<a~z
1)数字比字母要小。如 “7”<“F”;
2)数字0比数字9要小,并按0到9顺序递增。如 “3”<“8” ;
3)字母A比字母Z要小,并按A到Z顺序递增。如“A”<“Z” ;
4)同个字母的大写字母比小写字母要小32。如“A”<“a” 。
记住几个常见字母的ASCII码大小: “A”为65;“a”为97;“0”为 48。
另外还有128-255的ASCII字符
字符集简史
6000年前 象形文字
3000年前 字母表
1838年到1854年 Samuel F. B. Morse发明了电报,字母表中的每个字符对应于一系列短的和长的脉冲
1821年到1824年 Louis Braille发明盲文,6位代码,它把字符、常用字母组合、常用单字和标点进行编码。
一个特殊的escape代码表示后续的字符代码应解释为大写。一个特殊的shift代码允许后续代码被解释为数字。
1931年 CCITT标准化Telex代码,包括Baudot #2的代码,都是包括字符和数字的5位代码。
1890年 早期计算机的字符码是从Hollerith卡片,6位字符码系统BCDIC(Binary-Coded Decimal Interchange Code:二进制编码十进制交换编码)
60年代 扩展为8位EBCDIC,IBM大型主机的标准
1967年 美国信息交换标准码(ASCII:American Standard Code for Information Interchange)
在字符长度是6位、7位还是8位的问题上产生了很大的争议。从可靠性的观点来看不应使用替换字符,
因此ASCII不能是6位编码,但由于费用的原因也排除了8位版本的方案(当时每位的储存空间成本仍很昂贵)。
这样,最终的字符码就有26个小写字母、26个大写字母、10个数字、32个符号、33个句柄和一个空格,总共128个字符码。
ASCII现在记录在ANSI X3.4-1986字符集-用于信息交换的7位美国国家标准码(7-Bit ASCII:7-Bit American National
Standard Code for Information Interchange),由美国国家标准协会(American National Standards Institute)发布。
图2-1中所示的ASCII字符码与ANSI文件中的格式相似。
ASCII国际问题
ASCII是美国标准,所以它不能良好满足其它讲英语国家的需要。例如英国的英镑符号(£)在哪里?
拉丁语字母表重音符号
使用斯拉夫字母表的希腊语、希伯来语、阿拉伯语和俄语。
汉字系统的中国象形汉字,日本和朝鲜。
1967年,国际标准化组织(ISO:International Standards Organization)推荐一个ASCII的变种,
代码0x40、0x5B、0x5C、0x5D、0x7B、0x7C和0x7D“为国家使用保留”,而代码0x5E、0x60和0x7E标为
“当国内要求的特殊字符需要8、9或10个空间位置时,可用于其它图形符号”。这显然不是一个最佳的国际解决方案,
因为这并不能保证一致性。但这却显示了人们如何想尽办法为不同的语言来编码的。
扩展ASCII
1981年 IBM PC ROM256个字符的字符集,即IBM扩展字符集
1985年11 Windows字符集被称作“ANSI字符集”,遵循了ANSI草案和ISO标准(ANSI/ISO 8859-1-1987,简“Latin 1”。
ANSI字符集的最初版本:
1987年4月代码页437,字符的映像代码,出现在MS-DOS 3.3
双字节字符集
双字节字符集(DBCS:double-byte character set),解决中国、日本和韩国的象形文字符和ASCII的某种兼容性。
DBCS从256代码开始,就像ASCII一样。与任何行为良好的代码页一样,最初的128个代码是ASCII。
然而,较高的128个代码中的某些总是跟随着第二个字节。
这两个字节一起(称作首字节和跟随字节)定义一个字符,通常是一个复杂的象形文字。
键盘常用ASCII码
ESC键 VK_ESCAPE (27)
回车键: VK_RETURN (13)
TAB键: VK_TAB (9)
Caps Lock键: VK_CAPITAL (20)
Shift键: VK_SHIFT (16)
Ctrl键: VK_CONTROL (17)
Alt键: VK_MENU (18)
空格键: VK_SPACE (32)
退格键: VK_BACK (8)
左徽标键: VK_LWIN (91)
右徽标键: VK_LWIN (92)
鼠标右键快捷键:VK_APPS (93)
Insert键: VK_INSERT (45)
Home键: VK_HOME (36)
Page Up: VK_PRIOR (33)
PageDown: VK_NEXT (34)
End键: VK_END (35)
Delete键: VK_DELETE (46)
方向键(←): VK_LEFT (37)
方向键(↑): VK_UP (38)
方向键(→): VK_RIGHT (39)
方向键(↓): VK_DOWN (40)
F1键: VK_F1 (112)
F2键: VK_F2 (113)
F3键: VK_F3 (114)
F4键: VK_F4 (115)
F5键: VK_F5 (116)
F6键: VK_F6 (117)
F7键: VK_F7 (118)
F8键: VK_F8 (119)
F9键: VK_F9 (120)
F10键: VK_F10 (121)
F11键: VK_F11 (122)
F12键: VK_F12 (123)
Num Lock键: VK_NUMLOCK (144)
小键盘0: VK_NUMPAD0 (96)
小键盘1: VK_NUMPAD0 (97)
小键盘2: VK_NUMPAD0 (98)
小键盘3: VK_NUMPAD0 (99)
小键盘4: VK_NUMPAD0 (100)
小键盘5: VK_NUMPAD0 (101)
小键盘6: VK_NUMPAD0 (102)
小键盘7: VK_NUMPAD0 (103)
小键盘8: VK_NUMPAD0 (104)
小键盘9: VK_NUMPAD0 (105)
小键盘.: VK_DECIMAL (110)
小键盘*: VK_MULTIPLY (106)
小键盘+: VK_MULTIPLY (107)
小键盘-: VK_SUBTRACT (109)
小键盘/: VK_DIVIDE (111)
Pause Break键: VK_PAUSE (19)
Scroll Lock键: VK_SCROLL (145)
ASCII码的算法:
A在ascii中定义为01000001,也就是十进制65,有了这个标准后,当我们输入A时,计算机就可以通过ascii码知道输入的字符的二进制编码是01000001。而没有这样的标准,我们就必须自己想办法告诉计算机我们输入了一个A;没有这样的标准,我们在别的机器上就需要重新编码以告诉计算机我们要输入A。ascii码指的不是十进制,是二进制。只是用十进制表示习惯一点罢了,比如在ascii码中,A的二进制编码为01000001,如果用十进制表示是65,用十六进制表示就是41H。
在ascii码表中,只包括了一些字符、数字、标点符号的信息表示,这主要是因为计算机是美国发明的,在英文下面,我们使用ascii表示就足够了!但是在汉字输入下面,用ascii码就不能表示了,而汉字只是中国的通用表示,所以如果我们要在计算机中输入汉字,就必须有一个像ascii码的标准来表示每一个汉字,这就是中国的汉字国标码,它定义了汉字在计算机中的一个表示标准。通过这个标准,但我们输入汉字的时候,我们的输入码就转换为区位码,通过唯一的区位码得到这个汉字的字形码并显示出来。当然汉字的区位码在计算机中也是用二进制表示的!
二进制数转换为十进制数
二进制数第0位的权值是2的0次方,第1位的权值是2的1次方……
所以,设有一个二进制数:0110 0100,转换为10进制为:
下面是竖式:
0110 0100 换算成 十进制
第0位 0 * 2^0 = 0
第1位 0 * 2^1 = 0
第2位 1 * 2^2 = 4
第3位 0 * 2^3 = 0
第4位 0 * 2^4 = 0
第5位 1 * 2^5 = 32
第6位 1 * 2^6 = 64
第7位 0 * 2^7 = 0
---------------------------
100
用横式计算为:
0 * 2^0 + 0 * 2^1 + 1 * 2^2 +0*2^3+ 0 * 2^4 + 1 * 2^5 + 1 * 2^6 + 0 * 2^7 = 100
0乘以多少都是0,所以我们也可以直接跳过值为0的位:
1 * 2^2 + 1 * 2^5 + 1 * 2^6 = 100
6.2.2 八进制数转换为十进制数
八进制就是逢8进1。
八进制数采用 0~7这八数来表达一个数。
八进制数第0位的权值为8的0次方,第1位权值为8的1次方,第2位权值为8的2次方……
所以,设有一个八进制数:1507,转换为十进制为:
用竖式表示:
1507换算成十进制。
第0位 7 * 8^0 = 7
第1位 0 * 8^1 = 0
第2位 5 * 8^2 = 320
第3位 1 * 8^3 = 512
--------------------------
839
同样,我们也可以用横式直接计算:
7 * 8^0 + 0 * 8^1 + 5 * 8^2 + 1 * 8^3 = 839
结果是,八进制数 1507 转换成十进制数为 839
6.2.3 八进制数的表达方法
C,C++语言中,如何表达一个八进制数呢?如果这个数是 876,我们可以断定它不是八进制数,因为八进制数中不可能出7以上的阿拉伯数字。但如果这个数是123、是567,或12345670,那么它是八进制数还是10进制数,都有可能。
所以,C,C++规定,一个数如果要指明它采用八进制,必须在它前面加上一个0,如:123是十进制,但0123则表示采用八进制。这就是八进制数在C、C++中的表达方法。
由于C和C++都没有提供二进制数的表达方法,所以,这里所学的八进制是我们学习的,CtC++语言的数值表达的第二种进制法。
现在,对于同样一个数,比如是100,我们在代码中可以用平常的10进制表达,例如在变量初始化时:
int a = 100;
我们也可以这样写:
int a = 0144; //0144是八进制的100;一个10进制数如何转成8进制,我们后面会学到。
千万记住,用八进制表达时,你不能少了最前的那个0。否则计算机会通通当成10进制。不过,有一个地方使用八进制数时,却不能使用加0,那就是我们前面学的用于表达字符的“转义符”表达法。
6.2.4 八进制数在转义符中的使用
我们学过用一个转义符'/'加上一个特殊字母来表示某个字符的方法,如:'/n'表示换行(line),而'/t'表示Tab字符,'/''则表示单引号。今天我们又学习了一种使用转义符的方法:转义符'/'后面接一个八进制数,用于表示ASCII码等于该值的字符。
比如,查一下第5章中的ASCII码表,我们找到问号字符(?)的ASCII值是63,那么我们可以把它转换为八进值:77,然后用 '/77'来表示'?'。由于是八进制,所以本应写成 '/077',但因为C,C++规定不允许使用斜杠加10进制数来表示字符,所以这里的0可以不写。
事实上我们很少在实际编程中非要用转义符加八进制数来表示一个字符,所以,6.2.4小节的内容,大家仅仅了解就行。
6.2.5 十六进制数转换成十进制数
2进制,用两个阿拉伯数字:0、1;
8进制,用八个阿拉伯数字:0、1、2、3、4、5、6、7;
10进制,用十个阿拉伯数字:0到9;
16进制,用十六个阿拉伯数字……等等,阿拉伯人或说是印度人,只发明了10个数字啊?
16进制就是逢16进1,但我们只有0~9这十个数字,所以我们用A,B,C,D,E,F这五个字母来分别表示10,11,12,13,14,15。字母不区分大小写。
十六进制数的第0位的权值为16的0次方,第1位的权值为16的1次方,第2位的权值为16的2次方……
所以,在第N(N从0开始)位上,如果是是数 X (X 大于等于0,并且X小于等于 15,即:F)表示的大小为 X * 16的N次方。
假设有一个十六进数 2AF5, 那么如何换算成10进制呢?
用竖式计算:
2AF5换算成10进制:
第0位: 5 * 16^0 = 5
第1位: F * 16^1 = 240
第2位: A * 16^2 = 2560
第3位: 2 * 16^3 = 8192
---------------------------------
10997
直接计算就是:
5 * 16^0 + F * 16^1 + A * 16^2 + 2 * 16^3 = 10997
(别忘了,在上面的计算中,A表示10,而F表示15)
现在可以看出,所有进制换算成10进制,关键在于各自的权值不同。
假设有人问你,十进数 1234 为什么是 一千二百三十四?你尽可以给他这么一个算式:
1234 = 1 * 10^3 + 2 * 10^2 + 3 * 10^1 + 4 * 10^0
6.2.6 十六进制数的表达方法
如果不使用特殊的书写形式,16进制数也会和10进制相混。随便一个数:9876,就看不出它是16进制或10进制。
C,C++规定,16进制数必须以 0x开头。比如 0x1表示一个16进制数。而1则表示一个十进制。另外如:0xff,0xFF,0X102A,等等。其中的x也也不区分大小写。(注意:0x中的0是数字0,而不是字母O)
以下是一些用法示例:
int a = 0x100F;
int b = 0x70 + a;
至此,我们学完了所有进制:10进制,8进制,16进制数的表达方式。最后一点很重要,C/C++中,10进制数有正负之分,比如12表示正12,而-12表示负12,;但8进制和16进制只能用达无符号的正整数,如果你在代码中里:-078,或者写:-0xF2,C,C++并不把它当成一个负数。
6.2.7 十六进制数在转义符中的使用
转义符也可以接一个16进制数来表示一个字符。如在6.2.4小节中说的 '?' 字符,可以有以下表达方式:
'?' //直接输入字符
'/77' //用八进制,此时可以省略开头的0
'/0x3F' //用十六进制
同样,这一小节只用于了解。除了空字符用八进制数 '/0' 表示以外,我们很少用后两种方法表示一个字符。
6.3 十进制数转换到二、八、十六进制数
6.3.1 10进制数转换为2进制数
给你一个十进制,比如:6,如果将它转换成二进制数呢?
10进制数转换成二进制数,这是一个连续除2的过程:
把要转换的数,除以2,得到商和余数,
将商继续除以2,直到商为0。最后将所有余数倒序排列,得到数就是转换结果。
听起来有些糊涂?我们结合例子来说明。比如要转换6为二进制数。
“把要转换的数,除以2,得到商和余数”。
那么:
要转换的数是6, 6 ÷ 2,得到商是3,余数是0。 (不要告诉我你不会计算6÷3!)
“将商继续除以2,直到商为0……”
现在商是3,还不是0,所以继续除以2。
那就: 3 ÷ 2, 得到商是1,余数是1。
“将商继续除以2,直到商为0……”
现在商是1,还不是0,所以继续除以2。
那就: 1 ÷ 2, 得到商是0,余数是1 (拿笔纸算一下,1÷2是不是商0余1!)
“将商继续除以2,直到商为0……最后将所有余数倒序排列”
好极!现在商已经是0。
我们三次计算依次得到余数分别是:0、1、1,将所有余数倒序排列,那就是:110了!
6转换成二进制,结果是110。
把上面的一段改成用表格来表示,则为:
被除数 计算过程 商 余数
6 6/2 3 0
3 3/2 1 1
1 1/2 0 1
(在计算机中,÷用 / 来表示)
如果是在考试时,我们要画这样表还是有点费时间,所更常见的换算过程是使用下图的连除:
(图:1)
请大家对照图,表,及文字说明,并且自已拿笔计算一遍如何将6转换为二进制数。
说了半天,我们的转换结果对吗?二进制数110是6吗?你已经学会如何将二进制数转换成10进制数了,所以请现在就计算一下110换成10进制是否就是6。
6.3.2 10进制数转换为8、16进制数
非常开心,10进制数转换成8进制的方法,和转换为2进制的方法类似,惟一变化:除数由2变成8。
来看一个例子,如何将十进制数120转换成八进制数。
用表格表示:
被除数 计算过程 商 余数
120 120/8 15 0
15 15/8 1 7
1 1/8 0 1
120转换为8进制,结果为:170。
非常非常开心,10进制数转换成16进制的方法,和转换为2进制的方法类似,惟一变化:除数由2变成16。
同样是120,转换成16进制则为:
被除数 计算过程 商 余数
120 120/16 7 8
7 7/16 0 7
120转换为16进制,结果为:78。
请拿笔纸,采用(图:1)的形式,演算上面两个表的过程。
6.4 二、十六进制数互相转换
二进制和十六进制的互相转换比较重要。不过这二者的转换却不用计算,每个C,C++程序员都能做到看见二进制数,直接就能转换为十六进制数,反之亦然。
我们也一样,只要学完这一小节,就能做到。
首先我们来看一个二进制数:1111,它是多少呢?
你可能还要这样计算:1 * 20 + 1 * 21 + 1 * 22 + 1 * 23 = 1 * 1 + 1 * 2 + 1 * 4 + 1 * 8 = 15。
然而,由于1111才4位,所以我们必须直接记住它每一位的权值,并且是从高位往低位记,:8、4、2、1。即,最高位的权值为23 = 8,然后依次是 22 = 4,21=2, 20 = 1。
记住8421,对于任意一个4位的二进制数,我们都可以很快算出它对应的10进制值。
下面列出四位二进制数 xxxx 所有可能的值(中间略过部分)
仅4位的2进制数 快速计算方法 十进制值 十六进值
1111 = 8 + 4 + 2 + 1 = 15 F
1110 = 8 + 4 + 2 + 0 = 14 E
1101 = 8 + 4 + 0 + 1 = 13 D
1100 = 8 + 4 + 0 + 0 = 12 C
1011 = 8 + 4 + 0 + 1 = 11 B
1010 = 8 + 0 + 2 + 0 = 10 A
1001 = 8 + 0 + 0 + 1 = 10 9
....
0001 = 0 + 0 + 0 + 1 = 1 1
0000 = 0 + 0 + 0 + 0 = 0 0
二进制数要转换为十六进制,就是以4位一段,分别转换为十六进制。
如(上行为二制数,下面为对应的十六进制):
1111 1101 , 1010 0101 , 1001 1011
F D , A 5 , 9 B
反过来,当我们看到 FD时,如何迅速将它转换为二进制数呢?
先转换F:
看到F,我们需知道它是15(可能你还不熟悉A~F这五个数),然后15如何用8421凑呢?应该是8 + 4 + 2 + 1,所以四位全为1 :1111。
接着转换 D:
看到D,知道它是13,13如何用8421凑呢?应该是:8 + 4 + 1,即:1101。
所以,FD转换为二进制数,为: 1111 1101
由于十六进制转换成二进制相当直接,所以,我们需要将一个十进制数转换成2进制数时,也可以先转换成16进制,然后再转换成2进制。
比如,十进制数 1234转换成二制数,如果要一直除以2,直接得到2进制数,需要计算较多次数。所以我们可以先除以16,得到16进制数:
被除数 计算过程 商 余数
1234 1234/16 77 2
77 77/16 4 13 (D)
4 4/16 0 4
结果16进制为: 0x4D2
然后我们可直接写出0x4D2的二进制形式: 0100 1101 0010。
其中对映关系为:
0100 -- 4
1101 -- D
0010 -- 2
同样,如果一个二进制数很长,我们需要将它转换成10进制数时,除了前面学过的方法是,我们还可以先将这个二进制转换成16进制,然后再转换为10进制。
下面举例一个int类型的二进制数:
01101101 11100101 10101111 00011011
我们按四位一组转换为16进制: 6D E5 AF 1B
在PASCAL中的编程:
var a:integer;
begin
write('Input a number:');
readln(a);
if a>255 then writeln('Bu zai fan wei');
if a<=255 then writeln(chr(a));
readln;
end.