负数的算术右移有什么规律?

发布于 2022-09-01 06:35:57 字数 534 浏览 29 评论 0

/* 
 * divpwr2 - Compute x/(2^n), for 0 <= n <= 30
 *  Round toward zero
 *   Examples: divpwr2(15,1) = 7, divpwr2(-33,4) = -2
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 15
 *   Rating: 2
 */
int divpwr2(int x, int n) {
    int div =(x + ((x >> 31) & ((1 << n) + ~0))) >> n;
    return div;
}

我的问题是答案的算式为什么那样写?

就是这一步

div =(x + ((x >> 31) & ((1 << n) + ~0))) >> n;

另外,问下负数在算术右移过程中有什么规律吗?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

骷髅 2022-09-08 06:35:57

你要知道原码和补码的概念,还有符号位。原码的数值部分是无符号的二进制数,正数的符号位是0,负数的符号位是1;补码的话,简单说一下,正数和原码一样,但是负数是原码的数值部分各位取反,末位加一。

计算机里我们看到的和用的数字都是原码,而底层一般都是用补码实现的,例如,-10的原码是[1]1010(假设符号位是一位[]),补码是[1]0110,算数右移一位变成[1]1011(因为是补码,算术右移,首位补符号位),这个数转换成原码是 [1]0101,也就是 -5,再移一位为[1]1101,转换成原码是[1]0011,是 -3.以此类推,至于规律,我也不知道有什么规律,不过移动的位数如果超过了数值所有位数,结果会是-1.

酒几许 2022-09-08 06:35:57

楼上说的很对,右移就是这样的。
如果你仔细观察一下规律,你会发现:

    对于任一一个整数n,n >> x 的结果是n/(2^x),如果出现小数,结果就取小于它的最大整数。(至于证明我也不知道,但这个规律很好用,而且和左移的规律有点像)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文