将整数舍入到最接近的int,该整数小于或等于它,并且是64的倍数

时间:2010-05-05 02:01:13

标签: c math

给定一个整数x,你如何返回一个小于或等于x的整数y和64的倍数?

6 个答案:

答案 0 :(得分:17)

简单地and使用(64-1)的位反转:

x = x & ~63
// 64  is 000...0001000000
// 63  is 000...0000111111
// ~63 is 111...1111000000

这基本上清除了较低的六位,这与将其四舍五入为64的倍数相同。请注意,这将向负数的负无穷大舍入,而不是向零,但这似乎是你的问题需要。

您可以在此四种变体中看到此处的行为:

#include <stdio.h>
int main (void) {
    int i;
    for (i = -10; i <= 10; i++) {
        printf ("%3d -> %3d\n", i, i & ~3);
    }
    return 0;
}

这会产生:

-10 -> -12
 -9 -> -12
 -8 ->  -8
 -7 ->  -8
 -6 ->  -8
 -5 ->  -8
 -4 ->  -4
 -3 ->  -4
 -2 ->  -4
 -1 ->  -4
  0 ->   0
  1 ->   0
  2 ->   0
  3 ->   0
  4 ->   4
  5 ->   4
  6 ->   4
  7 ->   4
  8 ->   8
  9 ->   8
 10 ->   8

请记住,这仅适用于2的幂(如2 6 = 64)和2的补码(ISO标准不要求该表示 - 有关详细信息,请参阅here - 但我永远不会看到一个不使用它的C环境,而且我已经处理过从最小的8051到最大的大型机的系统。如果你想使用任何其他数字作为除数,你应该使用正确的数学函数,如floor

答案 1 :(得分:5)

x是您希望向下舍入到n的最接近倍数的数字,您需要的方法是:

floor(x / n) * n

你可以在C ++中实现非常好(而不是C):

int n = 5;
for (int x = 0; x < 100; x++)
    cout << x << " -> " << (x / n) * n << endl;

答案 2 :(得分:3)

(x >> 6) << 6
首先向右移动6位,然后向左移动 - 低位填充空值 标志没问题

编辑:我认为大多数编译器会优化x / 64 * 64(以及任何除以2的小幂的除法/乘法)到相同的代码,因此这种位魔法没有实际需要,直到你希望你的代码看起来很酷:)

(并且AndreyT认为对于简单的代码有更好的优化,阅读他的post评论

答案 3 :(得分:2)

假设您需要最接近的此类整数并且您正在使用正数:

x = x / 64 * 64;

各种各样的黑客攻击看起来很吵,但在这种特殊情况下绝对不需要它们。

答案 4 :(得分:1)

int y = x;
while ( y % 64 )
    y--;

答案 5 :(得分:1)

对于无符号的整数

return 0

对于签名的注册

return floor(-MAXINT/64)*64

- )