X606C语言程序设计进制专项部分03
使用不同进制表示方格数量
不同进制的输出占位符
int main() {
/*
* 在C语言中
* 默认输出数值是10进制
* 想要表示8进制,前面加0
* 想要表示16进制,前面加0x
* 想要表示2进制,前面加0b
*
* 注意
* %i/%d 表示以10进制形式输出
* %o 表示以8进制形式输出
* %x 表示以16进制的形式输出
* 没有提供以2进制输出的占位符
*/
int num1 = 12;
int num2 = 014;
int num3 = 0xc;
int num4 = 0b1100;
printf("%i,%i,%i,%i\n",num1,num2,num3,num4); // 12,12,12,12
printf("%i,%d,%o,%x",num1,num2,num3,num4); // 12,12,14,c
}
十进制转二进制
/*
* 进制转换
* 十进制转二进制
* 除2倒序取余法
* 比如十进制数14
* 14 余数
* 2
* --
* 7 0
* 2
* --
* 3 1
* 2
* --
* 1 1
* 2
* --
* 0 1
*
* 此时已经做完了做商操作
* 然后就可以倒着取余了
* 所以二进制是
* 1110
*/
二进制转十进制
/*
* 二进制转十进制
* 规律:系数1 * 基数1(索引1) + 系数2 * 基数2(索引2) + ......
* 系数:二进制中每一位对应的值
* 基数:如果是二进制转十进制,基数就是2,八进制转十进制基数就是8
* 索引:从最低位开始(从右向左),比如1110
* 0对应0,1对应1,1对应2,1对应3
*
* 下面举一个栗子
* 1110
* 从最高位开始计算
* 1 * 2(3) + 1 * 2(2) + 1 * 2(1) + 0 * 2(0) = 14
*/
十进制与其它进制的相互转换
/*
* 十进制转八进制
* 规律:除8倒序取余,和十进制转二进制的做法是一样的
* 举一个栗子,下面是一个十进制
* 24
*
* 24
* 8
* --
* 3 0
* 8
* --
* 0 3
*
* 最终得出的八进制是30
* 在C程序中表示为030
*
* 十进制转十六进制
* 规律:除16倒序取余
* 再次举24的栗子
*
* 24
* 16
* --
* 1 8
* 16
* --
* 0 1
*
* 最终得出的十六进制是18
* 在C程序中表示为0x18
*/
/*
* 八进制转十进制
* 规律:系数1 * 基数1(索引1) + 系数2 * 基数2(索引2) + ......
* 就都是利用二进制的公式,只不过把基数换了一下
* 举一个栗子,下面是一个八进制数
* 030
*
* 3 * 8(1) + 0 * 8(0) = 24
*
* 十六进制转十进制
* 就不说什么了,直接举栗子
* 十六进制数18
*
* 1 * 16(1) + 8 * 16(0) = 24
*/
二进制与其它进制的相互转换
/*
* 二进制转其它进制
*
* 二进制转八进制
* 规律:3个二进制位就是1个八进制位,因为111(2) = 7(8)
* 从右往左,3个划分为1组,前面不够的补0
* 举一个栗子,下面是1个二进制数
*
* 01101101
*
* 001 101 101
* 1 5 5
*
* 所以01101101转换为8进制就是155
*
* 二进制转十六进制
* 规律:4个二进制位代表1个16进制位,因为1111(2) = 15(16)
* 从右往左,4个划分1组,前面不够的补0
* 举一个栗子,下面是1个二进制数
*
* 01101101
*
* 0110 1101
* 6 D
*
* 所以01101101转换为16进制就是6D
*/
二进制在内存中的不同表现形式
/*
* 二进制在内存中的不同表现形式
* 原码/反码/补码
* 1.正数的原码/反码/补码
* 举一个栗子
* 9
* int -> 4byte -> 32bit
* 0000 0000 0000 0000 0000 0000 0000 1001
*
* 对于正数来说,原码/反码/补码都是二进制
*
* 2.负数的原码/反码/补码
* 举一个栗子
* -9
* 1000 0000 0000 0000 0000 0000 0000 1001
* 二进制的最高位我们称之为符号位
* 符号位是1代表负数
*
* 2.1.负数的原码
* 负数的原码就是负数的二进制
* 1000 0000 0000 0000 0000 0000 0000 1001
*
* 2.2.负数的反码
* 负数的反码就是除了最高位(符号位),其它的按位取反
* 1111 1111 1111 1111 1111 1111 1111 0110
*
* 2.3.负数的补码
* 负数的补码就是负数的反码加1
* 1111 1111 1111 1111 1111 1111 1111 0111
*/
原码反码和补码的作用
/*
* 计算机为什么要有原码/反码/补码
* 1.1计算机只能做加法运算
*
* 1 + 1 -> 1 + 1
* 1 - 1 -> 1 + (-1)
* 3 * 3 -> 3 + 3 + 3
* 9 / 3 -> 9 + (-3) + (-3)
* 所以如果没有原码反码和补码,计算机可能会计算出错误的结果
* 举一个栗子
* 用原码进行1 - 1的运算,要求用二进制表示过程 原码
*
* 0000 0000 0000 0000 0000 0000 0000 0001 1
* 1000 0000 0000 0000 0000 0000 0000 0001 -1
* ---------------------------------------
* 1000 0000 0000 0000 0000 0000 0000 0010 -2
*
* 可见,由原码计算出现了错误的结果
* 再用反码进行计算 反码
*
* 0000 0000 0000 0000 0000 0000 0000 0001 1
* 1111 1111 1111 1111 1111 1111 1111 1110 -1
* ---------------------------------------
* 1111 1111 1111 1111 1111 1111 1111 1111
* Convert to original code
* 1000 0000 0000 0000 0000 0000 0000 0000 -0
*
* 可见,由反码计算出现了不需要的符号
* 再次用补码进行计算 补码
*
* 0000 0000 0000 0000 0000 0000 0000 0001 1
* 1111 1111 1111 1111 1111 1111 1111 1111 -1
* ---------------------------------------
* 10000 0000 0000 0000 0000 0000 0000 0000
* Out of storage range, discard high
* 0000 0000 0000 0000 0000 0000 0000 0000 0
*
* 可见,通过补码计算出了正确答案
*/
下面是计算结果是负数的情况