C语言学习——进制转换

进制转换:

日常生活中使用的是十进制数据,由于计算机的物理特性导致它只能识别二进制数据,我们在编程时使用的10进制数据,会被计算机转换成二进制数据再运算,为了理解编程时的一些奇怪现象,我们需要掌握二进制数据、八进制数据、十六进制数据。

二进制数据:

由0~1两个数字组成,逢2进1,由于计算机的运算器只能识别高低两种电流,所以它在运算时只能识别二进制数据。

十进制转换成二进制:

假如把x转换成二进制,x/2记录下余数,然后对商继续除以2,重复这个过程,直到商为0结束,然后把记录的余数倒序汇总,就得到了x的二进制。

例如:117转换成二进制
    117 / 2 余数1
    58 / 2 余数0
    29 / 2 余数1
    14 / 2 余数0
    7 / 2 余数1
    3 / 2 余数1
    1 / 2 余数1
    0
    117的二进制就是:1110101

八进制数据:

由0~7八个数字组成,逢8进1,早期使用它记录二进制数据,现在基本不再使用,文件的权限还依然使用8进制数据表示,所以还无法退出历史。

二进制数据转换八进制:

三位二进制对应一位八进制。

    000 0
    001 1
    010 2
    011 3
    100 4
    101 5
    110 6
    111 7
注意:

在C代码中,以0开头的是八进制数据,以%o输出的也八进制数据。

十六进制数据:

由0~9和a~f十六个字符组成,随着计算机的发展CPU的位数越来越多,输出的二进制也越来越长,随后科学家又发明出十六进制用于记用二进制数据。

二进制转换成十六进制:

四位二进制对应一位十六进制,超过9的用字母ABCDEF表示(不区分大小写)。

    1000 8
    1001 9
    1010 a
    1011 b
    1100 c
    1101 d
    1110 e 
    1111 f 

注意:

在C代码中,以0x开头的是十六进制数据,以%x,%p输出的是十六进制数据。

0713

任意进制转换成十进制:

每一个非0位带该公式求和 v*b^(n-1) 就得到了十进制。 ​ v 值 ​ b 进制 ​ n 位数

关于进制转换可能遇到的笔试题:

1、十进制转换成二进制、八进制、十六进制(以%o或%x为输出占位符)

统一先转换成二进制,然后再把二进制转换成八进制或十六进制。

2、在代码阅读题中遇到0123或0xabcdf

0开头的是8进制,0x开头的是十六进制,可以先转换成二进制再转换10进制,然后再运算。

3、输入一个整数转换成N进制(2<= N <= 35)

原码、反码、补码:

原码:

整数的绝对值转换成二进制,叫原码。

反码:

原码按位求反,叫反码。

补码:

正数的原码就是补码,负数的反码+1是补码。

十进制的数据是以补码形式存储在计算机中的,因为计算机的CPU中只有加法器,也就是只能运算加法,其它运算都是使用加法模拟的。

为了能计算出a-b也就是a + -b 所以需要使用特殊格式存储负数。

// 以8位计算机为例
24 - 15
24 + -15
00001111 -15的原码
11110000 -15的反码
11110001 -15的补码   
00011000 24的补码
00001001 结果是9
    
// 以32位计算机为例
00000000 00000000 00000000 00001111 -15的原码
11111111 11111111 11111111 11110000 -15的反码
11111111 11111111 11111111 11110001 -15的补码  
00000000 00000000 00000000 00011000 24的补码
00000000 00000000 00000000 00001001 结果是9
    
0xfffffff1
    
​

补码转换成十进制整数:

补码的两种解析方式:

无符号解析:

由于无符号数据全部是正数,所以补码就是原码,直接转换成十进制即可。

有符号解析:

根据补码的最高位判断它是整数的补码还是负数的补码。

最高位是1:它必然是负数的补码。

1、补码-1得到反码

2、反码按位求反,得到原码

3、原码转换成十进制数据,并在结果的前面加上负号。

最高位是0:它必然是正数的补码,直接转换成十进制即可。

int num = 11111111 11111111 11111011 00101110;
1、由于最高位是1,它必须是负数的补码
2、补码-1 得到反码
    11111111 11111111 11111011 00101101
3、反码 按位求反 得到 原码
    00000000 00000000 00000100 11010010
    1024+128+64+16+2 
    -1234

注意:

当遇到补码转换成十进制数据的笔试题时,必须有是否是有符号信息。

// 假如以下变量的补码是10110011,代码会输出什么,补码的符号信息已经包含在代码中了
char num;
printf("%hhd",num);
10110011
10110010
01001101
64+8+4+1   
-77

// 把以下补码转换成十进制数据,条件不够充分
11001100

注意:

一个整型变量的取值范围是环型状的,当它是最大值时再加1就会变成最小值,当它是最小值时减1就是变成最大值。

以char类型数据为例:
-128 
10000000 补码
01111111 -1后的补码,转换成十进制的结果是127
    
127
01111111 补码
10000000 加1后的补码,转换成十进制的结果是-128

char特殊的补码:
10000000 最小值(最高位是1,其余全是0)
01111111 最大值(最高位是0,其余全是1)
11111111 -1(所有二进制位都是)
// 以下循环执行多少次:
char cnt = 7, n = 0;
while(cnt)
{
   cnt -= 3;
    n++;
}
printf("%hhd\n",n);

7 	 45
-128  1
125   42
-1    42
-127  1
126   42
0     173

位运算符:

位运算符是针对数据的补码进行运算。

A & B 按位与运算,它是针对数据的补码进行按位与运算
    0 & 0 结果是0
    0 & 1 结果是0
    1 & 0 结果是0
    1 & 1 结果是1

A | B 按位与运算
    0 | 0 结果是0
    0 | 1 结果是1
    1 | 0 结果是1
    1 | 1 结果是1

A ^ B 按位异或运算
    0 ^ 0 结果是0 
    0 ^ 1 结果是1 
    1 ^ 0 结果是1 
    1 ^ 1 结果是0

~A 按位求反,是单目运算符
    ~0 结果是1 
    ~1 结果是0

x << n 把x的补码前n位丢掉,末尾补上n个0,按位左移。
    10101100 << 3 01100000
    
x >> n 把x的补码后n位丢掉,前面n位,如果x是正数则补0,如果是负数则补1。
    char num = -3;
    printf("%hhd\n",num >> 2+1);
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值