c语言位运算十六进制转二进制,进制转换与位运算

本文详细介绍了C语言中不同进制的表示方法,包括二进制、八进制和十六进制,并提供了合法和非法的写法示例。同时,讲解了如何在C语言中进行二进制、八进制和十六进制的输出。此外,文章还讨论了计算机中数值的存储方式,包括原码、反码和补码的概念,以及位运算如按位与、按位或、按位异或等的操作。
部署运行你感兴趣的模型镜像

0进制转换和位运算

计算机中存储单位

什么是bit

bit是计算机中最小的信号但愿,可以表示高电平或者低电平。

以二进制“001”为例, 每一位都是一个bit。二进制只能由0/1组成,所以正好可以表示bit。

什么是byte

1个bit只能表示两种信号或者两种状态,表示的范围很小,例如英文字母26个就无法表示。所以规定8个bit一组作为一个数据的最小单元。即8bit=1byte。ASCII码表中的一个字符为一个byte。

1位二级制数可以表示的状态的个数是2种。0 1

2位二进制数可以表示的状态的个数是2的2次幂。00 01 10 11

3位二进制数可以表示的状态的个数是2的3次幂。

8位二进制数可以表示的状态的个数是2的8次幂。也就是256种。

1kb=1024byte

1mb=1024kb

1gb=1024mb

1tb=1024gb

写法和程序输出方式

不同进制的写法(c语言和java语言)

二进制由0,1组成。以0b开头

//合法的二进制

int a = 0b101; //换算成十进制为 5

int b = -0b110010; //换算成十进制为 -50

int c = 0B100001; //换算成十进制为 33

//非法的二进制

int m = 101010; //无前缀 0B,相当于十进制

int n = 0B410; //4不是有效的二进制数字

八进制由0-1组成,以0开头

//合法的八进制数

int a = 015; //换算成十进制为 13

int b = -0101; //换算成十进制为 -65

int c = 0177777; //换算成十进制为 65535

//非法的八进制

int m = 256; //无前缀 0,相当于十进制

int n = 03A2; //A不是有效的八进制数字

十六由0-9、a-f组成进制以0x开头

//合法的十六进制

int a = 0X2A; //换算成十进制为 42

int b = -0XA0; //换算成十进制为 -160

int c = 0xffff; //换算成十进制为 65535

//非法的十六进制

int m = 5A; //没有前缀 0X,是一个无效数字

int n = 0X3H; //H不是有效的十六进制数字

二进制数、八进制数和十六进制数的输出

short

int

long

八进制

%ho

%o

%lo

十进制

%hd

%d

%ld

十六进制

%hx 或者 %hX

%x 或者 %X

%lx 或者 %lX

#include

int main()

{

short a = 0b1010110; //二进制数字

int b = 02713; //八进制数字

long c = 0X1DAB83; //十六进制数字

printf("a=%#ho, b=%#o, c=%#lo\n", a, b, c); //以八进制形似输出

printf("a=%hd, b=%d, c=%ld\n", a, b, c); //以十进制形式输出

printf("a=%#hx, b=%#x, c=%#lx\n", a, b, c); //以十六进制形式输出(字母小写)

printf("a=%#hX, b=%#X, c=%#lX\n", a, b, c); //以十六进制形式输出(字母大写)

return 0;

}

在占位符中的#代表输出前缀,运行结果:

a=0126, b=02713, c=07325603

a=86, b=1483, c=1944451

a=0x56, b=0x5cb, c=0x1dab83

a=0X56, b=0X5CB, c=0X1DAB83

在内存中的表示方式

数值类型数据通常采用二进制数的最高位来表示符号,用0表示正数,1表示负数。

例如二进制数+1101000在计算机内表示为

内存中

1

1

1

0

1

0

0

0

真值

+

1

1

0

1

0

0

0

所有的数在计算机中都是以补码的形式存储的。正数的补码 == 原码。

原码、反码、补码

原码

原码就是符号位加上真值的绝对值,即用第一位表示符号,其余位表示值

二进制位的首位标识该二进制数是一个正数还是负数,正数为0,负数为1

正数: 10 的原码 –> 0000 0000 0000 0000 0000 0000 0000 1010

负数:-10 的原码 –> 1000 0000 0000 0000 0000 0000 0000 1010

反码

正数的反码 == 原码

负数的反码是在其原码的基础上,符号位(首位)不变,其余各个位取反

正数: 10 的原码 –> 0000 0000 0000 0000 0000 0000 0000 1010

负数:-10 的原码 –> 1000 0000 0000 0000 0000 0000 0000 1010

正数: 10 的反码 –> 0000 0000 0000 0000 0000 0000 0000 1010

负数:-10 的反码 –> 1111 1111 1111 1111 1111 1111 1111 0101

补码

正数的补码 == 原码

负数的补码是在其反码的基础上加1

正数: 10 的原码 –> 0000 0000 0000 0000 0000 0000 0000 1010

负数:-10 的原码 –> 1000 0000 0000 0000 0000 0000 0000 1010

正数: 10 的反码 –> 0000 0000 0000 0000 0000 0000 0000 1010

负数:-10 的反码 –> 1111 1111 1111 1111 1111 1111 1111 0101

正数: 10 的补码 –> 0000 0000 0000 0000 0000 0000 0000 1010

负数:-10 的补码 –> 1111 1111 1111 1111 1111 1111 1111 0110

不同进制数据计算和转换

不同进制数据计算

十进制数据计算 略

二进制数据计算 每位相加,逢2进1.

0b1101+0b1101010=0b1110111

​ 1 1 0 1

1 1 0 1 0 1 0

1 1 1 0 1 1 1

八进制数据计算:每位相加,逢8进1

0127+0765=1114

​ 1 2 7

​ 7 6 5

1 1 1 4

十六进制数据计算:逢16进1。其中a=10;b=11;c=12;d=13;e=14;f=15;

0x1ab+0x99a=b45

​ 1 a(10) b(11)

​ 9 9 a(10)

​ b(11) 20-16=4 21-16=5

任意进制转十进制

系数:每一位的数字

以157为例,个位系数是7,十位系数是5,百位系数是1

基数:几进制,基数就是几。十进制基数为十。

权:一个数据从右往左数,从0开始对每一位数据进行编号,这个编号就是这个位置上的权。

数字:157

权 :210

转换方式:任意进制到十进制的转换都等于“这个数据的各个位上的系数乘以基数的权次幂相加的和”

十进制:157=7X10^0+5X10^1+1X10^2

二进制:0b110=0x2^0+1×2^1+1×2^2=0+2+4=6

八进制:0110=0x8^0+1×8^1+1×8^2 = 0+8+64=72

十六进制:0xabc=12×16^0+11×16^1+10×16^2=12+176+2560=2748

十进制转任意进制

转换方式:把十进制的数字除以基数取余数,直到商为0,再将余数反转。

100转二进制为 0b1100100

100/2=50余0

50/2=25余0

25/2=12余1

12/2= 6余0

6/2= 3余0

3/2= 1余1

1/2= 0余1

100转8进制为0144

100/8=12余4

12/8= 1余4

​ 1/8= 0余1

100转16进制为0x64

100/16=6余4

​ 6/16=0余6

十进制和二进制利用8421码快速转换

二进制

1

1

1

1

1

1

1

1

十进制

128

64

32

16

8

4

2

1

11011=1+2+0+8+16=27

位运算

&

|

^

~

<<

>>

>>>

按位与

按位或

按位异或

按位取反

左移

右移

无符号右移

位运算符连接二进制数值,返回二进制数值。

补码:原码取反+1

&按位与[双目运算符—连接两个操作数]

同1为1,否则为0

3&4的结果:

int 3的二进制:0b11。由于每个int占4个字节也就是8的4次方个bit,即32位。

int 4的二进制:0b100

0000 0000 0000 0000 0000 0000 0000 0011

0000 0000 0000 0000 0000 0000 0000 0100

0000 0000 0000 0000 0000 0000 0000 0000

即3&4=0

|按位或[双目运算符—连接两个操作数]

只要有一个为1则结果为1,否则为0

3|4的结果

0000 0000 0000 0000 0000 0000 0000 0011

0000 0000 0000 0000 0000 0000 0000 0100

0000 0000 0000 0000 0000 0000 0000 0111

即3|4=111=7

^按位异或[双目运算符—连接两个操作数]

相同为0,不同为1

3^4的结果

0000 0000 0000 0000 0000 0000 0000 0011

0000 0000 0000 0000 0000 0000 0000 0100

0000 0000 0000 0000 0000 0000 0000 0111

即3^4=111=7

一个数据对相同的数据异或两次,其值不变。

~按位取反[单目运算符—一个操作数]

每位取反

~3

0000 0000 0000 0000 0000 0000 0000 0011

1111 1111 1111 1111 1111 1111 1111 1100

首位为1说明是负数,负数以其正值的补码形式存在。

所以想转为10进制的话就是已知补码求原码,即补码减1,然后取反,但是减法太麻烦。

还有一种思路就是将负数的补码先取反,然后加1,最高位置换为1就是原码。

1111 1111 1111 1111 1111 1111 1111 1100 取反

0000 0000 0000 0000 0000 0000 0000 0011 加1

0000 0000 0000 0000 0000 0000 0000 0100 最高位置换为1

1000 0000 0000 0000 0000 0000 0000 0100 即为-4

>>左移 <

让操作数乘以2的n次幂 n就是移动的位数

让操作数除以2的n次幂 n就是移动的位数

int i=3<<2;//3*2^2=12

往左边移动两位,右边空出两位,左边两位被挤掉,右边空位用0补全。

0000 0000 0000 0000 0000 0000 0000 0011

0000 0000 0000 0000 0000 0000 0000 1100 0X2^0+0*2^1+1X2^2+1X2^3=4+8=12

int i=32>>2;//32/2^2=8

往右边移动两位,左边空出两位,右边两位被挤掉,左边空位用看符号位,符号位为0用0补,符号位为1用1补。

0000 0000 0000 0000 0000 0000 0010 0000

0000 0000 0000 0000 0000 0000 0000 1000 0x2^0+0x2^1+0x2^2+1×2^3=8

int i=-32>>2=-8

原码1000 0000 0000 0000 0000 0000 0010 0000

反码1111 1111 1111 1111 1111 1111 1101 1111

补码1111 1111 1111 1111 1111 1111 1110 0000

负数右移两位是对补码右移两位得到右移后的补码

补码1111 1111 1111 1111 1111 1111 1111 1000

补码取反,加1,高位置换为1即为原码。

取反0000 0000 0000 0000 0000 0000 0000 0111

加一0000 0000 0000 0000 0000 0000 0000 1000

原码1000 0000 0000 0000 0000 0000 0000 1000 即为-8

您可能感兴趣的与本文相关的镜像

Python3.10

Python3.10

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值