Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2793200
  • 博文数量: 471
  • 博客积分: 7081
  • 博客等级: 少将
  • 技术积分: 5369
  • 用 户 组: 普通用户
  • 注册时间: 2012-01-04 21:55
文章分类

全部博文(471)

文章存档

2014年(90)

2013年(69)

2012年(312)

分类: C/C++

2012-08-27 16:35:55

只用位运算来取绝对值
    这是一个非常有趣的问题。大家先自己想想吧,Ctrl+A显示答案。
    答案:假设x为32位整数,则x xor (not (x shr 31) + 1) + x shr 31的结果是x的绝对值
    
x shr 31是二进制的最高位,它用来表示x的符号。如果它为0(x为正),则not (x shr 31) + 1等于$00000000,异或任何数结果都不变;
如果最高位为1(x为负),则not (x shr 31) + 1等于$FFFFFFFF,x异或它相当于所有数位取反,异或完后再加一(正数的话等于没加)。


//右移运算 负数在左边添加1,正数在左边添加0 
 补1的话那补码不是变了吗 -4<<1 怎么还等于-2
因为计算机是以补码来做运算的,平时使用正数的话,正数的补码等于原码没留意而已

-4=10...000100(原)=11...11011(反)=11...11100(补)
-4>>1 = 11..1110(补) = 10...0001(补反)=100...010(补补=原)=-2


异或 1 取反 0 原数

点击(此处)折叠或打开

  1. #include

  2. int int_abs(int x)
  3. {
  4. int y=x>>31;//int 是32位,以补形式存储
  5. printf("%d\n",y);//11111111 11111111 111111111 11111111这是-1的补码
  6. return (x^y)-y;//由补码求原码取反加1,-y等于+1
  7. }

  8. int main()
  9. {
  10. int x=-10,absx;
  11. absx=int_abs(x);
  12. printf("%d",absx);
  13. return 0;
  14. }
  15. /*
  16. -1
  17. 10Press any key to continue
  18. 已知一个数的补码,求原码的操作分两种情况:
  19. (1)如果补码的符号位为“0”,表示是一个正数,所以补码就是该数的原码。
  20. (2)如果补码的符号位为“1”,表示是一个负数,求原码的操作可以是:符号位为1,其余各位取反,然后再整个数加1。
  21. 例如,已知一个补码为11111001,则原码是10000111(-7):因为符号位为“1”,表示是一个负数,所以该位不变,仍为“1”;
  22. 其余7位1111001取反后为0000110;再加1,所以是10000111。
  23. */

阅读(3371) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~