#P1002. 进制和编码

进制和编码

c++关键字

autobreakcasechar、class、constcontinuedefaultdodoubleelseenum、explicit、export、
  extern、false、floatfor、friend、gotoifinlineintlong、mutable、namespace、new、
  noexcept、nullptr、operator、private、protected、public、register、reinterpret_cast、
  returnshortsignedsizeofstatic、static_assert、static_cast、structswitch、
  template、this、thread_local、throw、true、try、typedef、typeid、typename、unionunsigned、using、
  virtual、voidvolatilewchar_twhile、constexpr。

四种常用的数制及它们之间的相互转换:

进制 基数 基数个数 连数规律
十进制 0、1、2、3、4、5、6、7、8、9 10 10i10^i 逢十进一
二进制 0、1 2 2i2^i 逢二进一
八进制 0、1、2、3、4、5、6、7 8 8i8^i 逢八进一
十六进制 0、1、2、3、4、5、6、7、8、9 、A、B、C、D、E、F 16 16i16^i 逢十六进一

进制的标识

方法一:用一个下标来表明

例如:十进制(10)10(10)_{10} 二进制 (10)2(10)_2 十六进制 (10)16(10)_{16} 八进制(10)8(10)_8

方法二:用数值后面加上特定的字母

例如:十进制10D(D可省略)、二进制10B、十六进制10H、八进制10O

进制转换

十进制数转换为二进制数、八进制数、十六进制数的方法:短除反取余法

二进制数、八进制数、十六进制数转换为十进制数的方法:按权展开求和法

进制间的相互转换:

(1)二进制转十进制

方法:“按权展开求和”

例:(1011.01)2(1×23+0×22+1×21+1×20+0×21+1×22)(802100.25)(1011.01)_2=(1×2^3+0×2^2+1×2^1+1×2^0+0×2^{-1}+1×2^{-2})=(8+0+2+1+0+0.25)

=(11.25)10

规律:个位上的数字的次数是0,十位上的数字的次数是1,......,依次递增,而十分位的数字的次数是-1,百分位上数字的次数是-2,......,依次递减。

注意:不是任何一个十进制小数都能转换成有限位的二进制数。

(2)十进制转二进制

整数部分:“除以2取余,逆序排列”(短除反取余法)

例:(57)10=(111001)2(57)_{10}=(111001)_2

57÷2=28……1

28÷2=14……0

14÷2=7……0

7÷2=3……1

3÷2=1……1

1÷2=0……1

小数部分:“连续乘以基数R后,正取整数。”(乘基(正)取整法。)

例:(0.625)10=(0.101)2(0.625)_{10}=(0.101)_2

0.625*2=1.25.....取整数部分1

0.25*2=0.5.....取整数部分0

0.5*2=1.0.....取整数部分1

当小数部分为0时结束。

(3)二进制与八进制和十六进制间转换

十六进制是由0~15这些基本数字组成,其中最大的15对应的二进制为1111,所以四位二进制表示一位十六进制。同理三位二进制表示一位八进制。

二进制数转换成八进制数:从小数点开始,整数部分向左、小数部分向右,每3位为一组用一位八进制数的数字表示,不足3位的要用“0”补足3位,就得到一个八进制数.

八进制数转换成二进制数:把每一个八进制数转换成3位的二进制数,就得到一个二进制数。

例:将八进制的37.416转换成二进制数:

37.416

011111.100001110

即:(37.416)8(11111.10000111)2(37.416)_8=(11111.10000111)_2

例:将二进制的10110.0011转换成八进制:

010110.001100

26.14

即:(10110.011)2=(26.14)8(10110.011)_2=(26.14)_8

二进制数转换成十六进制数:从小数点开始,整数部分向左、小数部分向右,每4位为一组用一位十六进制数的数字表示,不足4位的要用“0”补足4位,就得到一个十 六进制数。

十六进制数转换成二进制数:把每一个十六进制数转换成4位的二进制数,就得到一个二进制数。

例:将十六进制数5DF.9转换成二进制:

5DF.9=0101 1101 1111.1001

即:(5DF.9)16(10111011111.1001)2(5DF.9)_{16}=(10111011111.1001)_2

例:将二进制数1100001.111转换成十六进制:

0110 0001.1110

61.E

即:(1100001.111)2(61.E)16(1100001.111)_2=(61.E)_{16}

注意:以上所说的二进制数均是无符号的数。这些数的范围如下表:

无符号位二进制数位数 数值范围 十六进制范围表示法
8位二进制数 0~255(255=2^8-1) 00H~FFH
16位二进制数 0~65535(65535=2^16-1) 0000H~FFFFH
32位二进制数 0~2^32-1 00000000H~FFFFFFFFH

带符号数的机器码表示方法

带符号二进制数用最高位的一位数来表示符号:0表示正,1表示负。

含符号位二进制数位数 数值范围
8位二进制数 -128~127
16位二进制数 -32768~+32767
32位二进制数 -2147483648~+2147483647

编码

ASCII码(American Standard Code for Information Interchange)美国标准信息交换代码,现成为世界交换代码标准。

ASCII 码是一种用 8 个比特组成的二进制编码(即一个字节),用于表示128个国际通用字符。

位置 分类 可见性
0~31,127 控制字符或通信专用字符 N
32 空格 Y/N
33~47,58~64,94~96,126 特殊字符(除字母/数字/空格/控制字符外的其他字符) Y
48~57 数字(按大小升序)
65~90 大写字母(按字母表升序)
97~122 小写字母(按字母表升序)

补:28=25627=1282^8 =256,2^7 = 128,这是因为在 ASCII 码中,把二进制最高位为 0 的数字都称为基本的 ASCII 码,其范围是 0 ∼ 127;把二进制最高位为1的数字都称为拓展的 ASCII 码,其范围是 0 ∼ 256。

补:一个汉字在计算机中占2个Byte。

机器数与真值

计算机中要处理的整数有“无符号”和“有符号”之分,“无符号”整数顾名思义就是不考虑正负的整数,可以直接用二进制表示,故只讨论“有符号”整数。

为简化机器中数据的运算操作,人们采用了原码、反码、补码等几种方法对数值位和符号位统一进行编码:

① 原码:

将一个整数表示成符号位+二进制串。符号位上,0表示正数,1表示负数。就是用第一位表示符号,其余位表示值,即机器数。

[+1]原=00000001

[-1]原=10000001

我们发现用原码表示,让符号位也参与计算,对于减法来说,结果是不正确的。这也就是为何计算机内部不使用原码表示一个数。为了解决原码做减法的问题,出现了反 码.

② 反码:

正数的反码是其本身;负数的反码是在其原码的基础上,符号位不变,其余各个位取反,即0变1,1变0。

[+1]=[00000001]原=[00000001]反

[-1]=[10000001]原=[11111110]反

我们发现反码计算的结果与正确结果差1,所以负数在反码的基础上+1就可以解决这个问题。

③ 补码:

正数的补码就是其本身;负数的补码是在其反码的基础上+1

[+1]=[00000001]原=[00000001]反=[00000001]补

[-1]=[10000001]原=[11111110]反=[11111111]补

逻辑运算

  • 逻辑非:!或¬,操作数的反值(!1=0,!0=1)。
  • 逻辑与:&&或∧,全部操作数都为真,结果才为真(1∧1=1,1∧0=0,0∧1=0,0∧0=0)。
  • 逻辑或:||或∨,至少一个操作数为真,结果才为真。(1∨1=1,1∨0=1,0∨1=1,0∨0=0)
  • 运算优先级:逻辑非>逻辑与>逻辑或。

可以简单理解为:非(乘方)>与(乘/除法)>或(加/减法)。

  • 按位与:&,参加运算的两个数,按二进制位进行“与”运算。如果两个相应位同时为1,该位结果为1,否则为0。(负数以补码形式参加运算)
  • 按位或:|,参加运算的两个数,按二进制位进行“或”运算。如果两个相应位有至少一个1,该位结果为1,否则为0。(负数以补码形式参加运算)
  • 按位异或:^(注意与“逻辑与”区分)或xor,参加运算的两个数,按二进制位进行“异或”运算。如果两个相应位为“异”(值不同),则该位结果为1,否则为0。(负数以补码形式参加运算)

特别的,在进行按位运算时,如果位数不够,需要在位数少的数前补0。

例如:13 |2=1101|0010=1111。

  • 逻辑表达式:由逻辑运算组合而成,返回值只有 T(True) 和F(False),C++中0表示假、非0表示真。