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