2010-05-05 76 views

回答

17

只需使用的(64-1)位反转and它:

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 = 64)和二进制补码(ISO标准没有强制要求 - 请参阅here了解详情 - 但我已经从来没有看到一个不使用它的C环境,我从事最恶劣的8051系统到最大的大型机)。如果你想使用除数的任何其他数字,你应该使用适当的数学函数,如floor

+0

嘿,这个工作在签名ints? – Plynx 2010-05-05 02:09:46

+0

伟大的黑客............. – aviraldg 2010-05-05 02:13:34

+0

感谢您的指定 - 虽然爱这个答案! – Plynx 2010-05-05 02:15:44

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; 
+0

权的方式来做到这一点,但是如果你正在处理一个小的,有限的y集合,那么硬编码的方法会更有效率(例如List alloc ators,etc.) – aviraldg 2010-05-05 02:06:54

+3

'cout << x << " ->“<<(x/n)* n << end;'不是C,我的朋友。 – 2010-11-04 04:09:42

+0

谢谢@Chris Lutz。我最好改变这一点。 – icio 2010-11-11 16:40:13

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

对于无符号整数

return 0 

对于签署整数

return floor(-MAXINT/64)*64 

;-)

+0

有趣的是,但幽默应该最好留在评论中,以免冒风险警察的愤怒:-) – paxdiablo 2010-05-05 02:12:08

+0

这实际上是一个事实上的正确答案。而且它比其他一些响应更好,当给定负值或-MAXINT时会失败。不过,也许OP意味着指定*最大的*整数,满足上述要求:) – Plynx 2010-05-05 02:13:28

+0

这取决于你如何解析这个问题。逻辑运算符在自然语言中的优先级通常有点不同;) – 2010-05-05 02:17:15

2

假设你需要最近这样的整数,并且您与正数工作:

x = x/64 * 64; 

各种各样的黑客入侵查看,但在这种特定情况下绝对不需要它们。

+0

除了每次最少显示比最快的部分快。编译器通常会在合理的情况下优化2个MULT DIV的功率(对于2的低功率)。 – jcolebrand 2010-05-05 04:11:42

+3

@drachenstern:不,只有当精确的意图无法通过语言表达时,点击才会更快。在这种特殊情况下,任何优秀的编译器都应该生成最高效的代码,如果它碰巧是一个“有点破解”,那么编译器应该使用它,而不是源代码的作者。不,mul/div不一定是优化的 - 这是一个古老的都市传说。他们通常被优化成适合每种情况的最有效的操作,这可能是一个转变或其他事情。事实上,这些日子很少有转变。 – AnT 2010-05-05 05:12:50

+1

最后,通过在源代码层面上使用一些小技巧,实际上可以减少发生高效优化的机会。换句话说,对于这样的直截了当的案例来说,黑客攻击通常会显得较慢,而不是像你似乎错误地相信的那样快。 – AnT 2010-05-05 05:13:58

3

(x >> 6) << 6
先右移6位,然后左下位填充零点。
带符号没有问题

编辑:我想大多数编译器将优化x/64 * 64(和任何分/用2小国乘),以相同的代码,所以在这样的位魔法不实际需要,直到你希望你的代码看起来真的很酷:)

(和AndreyT认为有是简单的代码,甚至更好的优化,阅读评论他post

+0

这实际上非常该死的光滑,你必须经常在C适当工作,是吧? – jcolebrand 2010-05-05 03:49:09

+0

@drachenstern:PL/SQL,其实:)只是梦想C或C++的工作 – 2010-05-05 03:53:50

+0

哈哈,嗯,whatashame。猜猜这是值得的实践吧? – jcolebrand 2010-05-05 04:13:20

相关问题