C语言:位运算符


运算符:
4个字节32位

  • (10<<8) | 2
    10: 0000 1010 (1个字节)
    10<<8: 0000 0000 0000 1010 0000 0000
    10<<8 = 10 * 28 = 2560
    2: 0000 0010
    (10<<8) | 2: 2048 0 512 0 0000 0 0 2 0 = 2562

或 |:
0 | 某一位,某一位不变
1 | 某一位,某一位变为1
与 &:
0 & 某一位,某一位变为0
1 & 某一位,某一位不变
异或 ^:
0 ^ 某一位,某一位不变
1 ^ 某一位,某一位取反

确定符号,确定数字,构造数字

  • 去掉最后一位:
    101101——10110
    右移1:>>1
  • 最后加一个0:
    101101——1011010
    左移1:<<1
  • 最后加一个1:
    101101——1011011
    先左移1:<<1
    再或1:| 1
  • 最后一位变成1:
    101100——101101
    或1:| 1
  • 最后一位变成0:
    101101——101100:
    与~1:&( ~ 1)
  • 最后一位取反
    101101——10110
    异或1:^1
  • 右数第k位变为1:
    101001——101101,k=3
    或(1<<(k-1)):| (1<<(k-1))
  • 右数第k位变为0:
    101101——101001,k=3
    与(1<<(k-1)):& (1<<(k-1))
  • 右数第k位取反:
    101101——101001,k=3
    异或(1<<(k-1)):^ (1<<(k-1))
  • 取末三位:
    1101101——101
    与7:& 0000 0111(7)
  • 取末k位:
    1101101——1101
    与(2k -1):& 0000 1111
    与((1<<k) -1):& 0000 1111
  • 取右数第k位:
    1101101——1,k=4
    先右移(k-1):>>(k-1)
    再与1:& 1
  • 右边连续的1变成0:
    100101111——100100000
    与(x+1):& (x+1)
  • 右边第一个1变成0:
    100101111——100111111
    或(x+1):| (x+1)
  • 右边连续的0变成1:
    11011000——11011111
    或(x-1):| (x-1)

位运算实现输出浮点数的整数部分(浮点数不能直接执行位操作)

int Sub(int a, int b)//a-b=a+(-b)
{//位运算实现减法
	for (int i = 1; i != 0; i <<= 1)
	{
		if (((~b+1) & i) != 0)//-b=~b+1
		{
			for (int j = i; j != 0; j <<= 1)
			{
				if ((a & j) != 0)
				{
					a ^= j;
				
				}
				else
				{
					a |= j;
					break;
				}
			}
		}
	}
	return a;
}
int MyFtoI(float f)//位操作实现输出浮点数的整数部分
{
	union Bit
	{
		//联合体内共用地址空间
		float f;
		struct M {
			unsigned int tail : 23;//尾数位
			unsigned int ex : 8;//指数位
			unsigned int flag : 1;//符号位
		} M;
	}tmp;

	//union Bit tmp;
	//if (fabs(f) < 0.000001)//fabs()对浮点数求绝对值
	if (f > -0.000001 && f < 0.000001)
	{
		return 0;
	}
	tmp.f = f;
	int e = Sub(tmp.M.ex, 127);//求出实际指数
	int tail = tmp.M.tail;//
	tail |= 0x00800000;//浮点数存储时,只存储1.之后的值,在这里将这个1补上
	tail >>= Sub(23, e);//右移去掉指数不能覆盖的尾数位
	if (tmp.M.flag == 1)//判断浮点数的符号位
	{
		tail *= -1;
	}

	return tail;
}
int MyFtoI(float f)//12.5fshu输出12

12.5=1100.1=1.1001*2^3
0
3+127=130=128+2;1000 0010
1001 00000000000000(190);0 1000 0010 1001 0000000000000000000

真实地址:小端模式:低地址——>放低数据
共享内存,从低地址覆盖,即结构体覆盖浮点数从尾数部分覆盖
十六进制:0x82480000——00004882:M
0x00480000——[000048]00:tail
0x00000082——[82]000000:ex
0x00000000——[0]0000000:flag

  8        2    4    8        0    0   0    0
[0100][0 001][0 100][1 000] 0000 0000 0000 0000
0000 0000 0100 1000 0000 0000 0000 0000:tail
0000 0000 1000 0000 0000 0000 0000 0000:0x00800000
0000 0000 1100 1000 0000 0000 0000 0000:tail|0x00800000
0000 0000 0000 0000 0000 0000 01100 100:tail>>(23-ex)

0100 0001 0100 1000 0000 0000 0000 0000:tail
0000 0000 0000 0000 0000 0000 1000 0010:tail>>23
0000 0000 0000 0000 0000 0000 1111 11110x000000ff
0000 0000 0000 0000 0000 000[0] 1000 0010:

[1]100 0001 0100 1000 0000 0000 0000 0000:tail
1111 1111 1111 1111 1111 111[1] 1000 0010:tail>>23

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值