Day4 内容梳理:
1、Chapter 2 基本数据类型(共4小节):
上一篇文:2.1 关键字,2.2 数据类型(字符型、整型、浮点型)
下(本篇文):2.3 进制转换, 2.4 数据存储的方式(原码反码补码)和数据溢出问题
目录
Chapter 2 数据类型
2.3 进制
(1)概念 & 性质
C语言中,可以直接定义八进制、十进制、十六进制的数字,但不能直接定义二进制。
二进制:数字范围0 - 1
无法在C语言中直接定义。
八进制:数字范围0 - 7
定义格式:以0开始,后续数字都在0到7之间
十进制:数字范围0 - 9
十六进制:数字范围0 - 9 & 字母范围 a - f (用a - f 或A - F的形式替代数字10 - 15)
定义格式:以0x开头。数字在0到9之间,字母在a到f之间
(2)进制转换
十进制👉二进制:“除二反序取余法”
(十进制 → 八进制、十进制 → 十六进制都是同理,区别是除的数为8或16)
每次除以2之后都记录 %2 的余数,除至被除数为0就停。然后将余数从后往前取。
例子:10除以2得5余0;5除以2得2余1;2除以2得1余0;1除以2得0余1;从后往前看,得到1010。
二进制👉十进制:“权值法”
(八进制 → 十进制、十六进制 → 十进制同理)
从二进制的个位开始,往高位依此是2^0、2^1......若位置上是0则不计入是1则计入。
例子:二进制1010得到 2^3 + 0 + 2^1 + 0 = 10
二进制👉八进制:3个一组划分
(二进制 → 十六进制同理,区别是按4个一组从低到高划分)
将二进制的数按3个一组从后往前分割,得到各组代表的数字,再按顺序排列。
例子:10101010 分割为 10 101 010,查表得到2 5 2,也就是252。
八进制👉十六进制:借助二进制中转一下
(十六进制 → 八进制同理,借助二进制转换)
把各个数字转化二进制,再把二进制按4个一组划分,得到十六进制。
2.4 数据存储的方式
(1)存储方式:原码、反码、补码
原码
一个数的原码就是它的二进制码。最高位是符号位,是0则为正数,是1则为负数。
例子:10的原码是 0000 1010;
-10的原码是 1000 1010
缺陷:当两个正数相减或一正一负相加时,必须先比较谁的绝对值更大,才能确定结果的正负,不利于加减运算。
反码
正数的反码等于它本身;对于负数,符号位的数不变,其他位的数取反(0变1,1变0)。
例子:-15的原码是 1000 1111
-15的反码是 1111 0000
缺陷:运算不方便。
补码
数值一律以补码的形式存储,加减计算是将两数相减转化正数和负数后,把补码相加。
正数的原码、反码、补码相同;
对于负数,补码是在反码的基础上进1。若进1后,补码超出8位,则舍去最高位。
##原码补码转换的例子:
原码为0000 0000,则其补码为0000 0001
原码为0000 1100,则其补码为0001 0000
原码为1110 0000,则其补码应为0000 0000而非 1 0000 0000
##补码运算的例子:计算机计算76 - 32 = ?
第1步,带符号转换成原码。76的原码为0100 1100,-32的原码为1010 0000
第2步,转换成补码(正负数的转换方式不同)。
若有负数,则先转化为反码,再对反码进1得到补码。
正数的原码等于补码,76的补码仍为0100 1100。
负数的原码转补码需要经过反码(最高位不变,其余为取反)。
-32的反码为1101 1111。
给负数的反码进1,-32的补码为:1110 0000。
第3步,补码相加得到:1 0010 1100
第4步,若超过8位则舍掉最高位。最终答案为 0010 1100,也就是数字44。
(2)数据溢出问题
定义:当给变量赋的值大于其数据类型能存放的最大范围时,数值会溢出。
符号位的溢出会改变数值的正负,因此选用数据类型时,小心不要溢出。
例子:char类型的取值范围是-128到127,下图则是数据溢出: