负数的除法和右移的区别

A和B两个函数的结果是相同的,求M和N.

#define M ? 
#define N ? 
int A(int x,int y) 
{ 
  int result = 0; 
  result = x*M+y/N; 
  return result; 
   
} 
  
int B(int x,int y) 
{ 
   int t = x; 
   x<<=5; 
   x-=t; 
   if(y<0)y +=7; 
   y>>=3; 
   return x+y; 
} 


解析:

M为31 N为8

x*M = x<<5 = x*2^5 = x*31,所以M为31

下面说下N是怎么得到的

对于无符号整数,除法和右移效果是一样的;

对于有符号的正整数,除法和右移的效果也是一样的;

对于有符号的负整数,除法和右移的效果是不一样的;

比如:

-3/2 = -1;

-3>>1是多少呢?我们可以将其按照8位二进制展开

-3的8位二进制是1000 0011,负数在计算机中是以补码的形式存储的,所以还需要将其转换成补码

1000 0011转换成反码 1111 1100(最高位符号位不动), 再加1转换成补码1111 1101

接着将其右移1位,由于是有符号负整数,所以最高位补1,变为1111 1110

接着将其还原成原码,1111 1110减1变反码1111 1101,接着反码取反变原码1000 0010,转换成十进制是-2,也就是说-3>>1得到的是-2

其实这是因为除法是向0取整,而右移位是向负取整

-3/2=-1.5=-1(向0取整),-3>>1=-1.5=-2(向负取整);

如果我们需要右移达到的效果和除法一样,可以采取下列公式:

假设除数为2^N,负数x的除法可以用以下方法来代替:

(x + 2^N - 1) >> N

在这道题里就是(x+2^3-1)>>3 =(x+7)>>3

也就是说A函数中的y/N和B函数中的if(y<0)y +=7; y>>=3; 取到的效果是一样的,都是y/8,所以N为8




  • 5
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值