C语言中,你不得不知的位运算符特性

我突然问你,-1用二进制如何表示?你最快多久能给我答案????,-1全是1啊

二进制如何表示负数

最左一位表示正负----->1为负,0为正

将-5用二进制表示:

好的算法:

(1)先加1,得-4
(2)求绝对值,得4
(3)二进制表示:00000100
(4)求补: 11111011

以前我都是这么算的:

-5->10000101
求补->11111010
加1 ->11111011

还是上面的好算啊


将一个负数从二进制转换为十进制:

拿-5:11111011来说

(1)求补 : 00000100
(2)换为十进制 :4
(3)变符号 :-4
(4)减1 : -5

现在来思考:

使用补码表示数字时,用n位可以存储的最大正数是2 (n-1) -1 ->>括号表示次方

用n位存储的最小负数:-2(n-1),为什么绝对值不一样呢???

正数很好理解:拿8位来说,第一位为符号位,那么最大:1111111,7个1,所以最大表示:为127

负数:看上面 ->将一个负数从二进制转换为十进制:

要最小,则上面第二部,十进制最大:1111111->127,变号,减一 ->>>-128

呵呵,很简单吧


C中我们说unsigned修饰符可将变量的存储值增加1倍,为什么呢?

因为没了符号位,所以最大表示正数:2(n)-1,原来是2(n-1)-1

你被骗了没有,这哪是2倍啊,呵呵


byte&bit:

这里有道面试题:

现有百兆光纤连接器A和B,机器A提供web网页服务,网页大小为1K字节,机器B通过浏览器下载,求最有可能下载速度的最大上限(C)

C>10000页/秒

光纤的上行和下行是一样的:要知道网络传输速度的单位.

我们一般说的百兆,千兆网络的单位是bps(比特率,即bit/s),比如我们说网卡或光纤的传输速度是百兆,也就是100Mbps.而在实际应用中(Windows,快车,迅雷等)

使用的传输单位是字节/秒(Byte/s). 1字节=8位,因此100M的光纤速度约等于12.5M.


按位与(&):某些位清零

按位或(|):某些位置一

按位异或(^):不同为1,相同为0

特性:

1. a ^ b=b ^ a
2. a ^ b ^ c=a ^(b ^ c)=(a ^ b) ^ c
根据以上我们可以推出以下结论:

1.d = a ^ b ^ c 可以推出 a = d ^ b ^ c.
首先需要知道: a ^ a=0  a ^ 0=a
理由: d=a ^ b ^ c   ->  d ^( d ^ a)=a ^ b ^ c ^( d ^ a)   ->  a=d ^ b ^ c
2.   a ^ b ^ a = b 这个就不需要说了吧

异或还有一个有趣的应用,它可以在不用额外存储单元的情况下高效的交换两个数值

如:交换 i1和i2:

i1 ^= i2;
i2 ^=i1;
i1 ^=i2;

证明很简单的,如下:

i1=i1 ^ i2
i2=i2 ^ i1=i2 ^(i1 ^ i2)=(i2 ^i2) ^i1=i1;
i1=i1 ^ i2=(i1 ^ i2) ^i1=(i1 ^ i1) ^ i2=i2;

取反(~):

这个运算符也挺有趣的,请问,0的取反是多少?呵呵,对的,-1,很神奇吧.

问:为了将一个整数w的最低位置0,用什么办法好?

这还不简单: w &=0xFFFFFFFE

回答的很对,但这会在一个用32位表示整数的机器上工作的很好,要求可移植性更好,有什么办法?

呵呵, w &= ~1; ,想到了没有.(对1取反,只有最后一位是0)

左移:<<

右边空出用0填补.

在不溢出的情况下,每左移一位相当于乘以2


右移:>>

左边空出的位用0或者1填补.正数用0填补,负数用1填补(不同环境填补方式可能不一样).

下面是"C语言解惑"中的一道题目:

y=-1;

y <<=3; //求y ->> -8

y >>=3; //求y? ->> ??

第二个答案是???,"C语言解惑"这么解释的:

有些计算机进行右移操作时会不保留操作数的符号位,而且C语言本身也不保证移位操作的结果在数学意思上肯定是正确的,

呵呵,很恶心的东西.不过在一般计算机系统上结果的确是-1,比如windows,ubuntu.


位域:

将信息打包到一个字节或一个字节的几位->>>节约内存空间

如下:

#include <stdio.h>
/************************************************************************/
/* pack包含6个成员,第一个成员没有命名,:3指出占用3位                     */
/* 成员f1占用1位,等等............................                       */
/************************************************************************/
struct pack
{
	unsigned int :3;
	unsigned int f1:1;
	unsigned int f2:1;
	unsigned int f3:1;
	unsigned int type:8;
	unsigned int index:18;
};

int main(void)
{
	struct pack p;
	printf("sizeof:%d\n",sizeof(p));     
	p.f1=1;
	p.f2=2;
	p.type=7;
	printf("f1:%d-f2:%d-type:%d\n",p.f1,p.f2,p.type);
	return 0;
}

结果:

sizeof:4
f1:1-f2:0-type:7




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值