我试图找到用C语言计算以下内容的最快方法:
p = 2^(ceil(log2(x)));到目前为止,看看堆栈溢出(和其他地方)中的答案,我已经了解到了这一点:
#define LOG2(X) ((int) (8*sizeof (unsigned long long) - __builtin_clzll((X)) - 1))
int p = 1 << LOG2( (unsigned long long)x );x将始终是一个整数(int类型),并且大于零。我从这个堆栈溢出的LOG2 question中获得了这个解决方案。有几个好的答案,但它们似乎都是四舍五入(包括这个)。我要集合一下。我对这些解决方案感到不舒服,不能把它们修改成集合起来。任何帮助都将不胜感激!
发布于 2015-05-28 02:20:24
管它呢,我会给你答案的。
若要将“舍入”转换为“舍入”,只需计算日志(x-1)四舍五入并将1添加到结果中即可。
一般说来,向上舍入的结果总是比四舍五入多1(即地板(某某物)和ceil(某物)相差1),除非某物是一个确切的整数;在这种情况下,当你的输入是2的幂时,从输入中减去1并将1加到结果中的技巧是一般的;它适用于任何单调函数,如log()。
为了获得完全的正确性,您可能希望将特殊情况0作为输入,但对于原始公式也是如此,因为log(0)是未定义的。
发布于 2015-05-28 04:57:30
我很确定:
2^(ceil(log2(x)))可以将其理解为大于或等于x的2的最低幂,但x为零的情况除外,后者是未定义的。
在这种情况下,可以找到以下内容:
unsigned int fn (unsigned int x) {
if (x == 0) return 0;
unsigned int result = 1;
while ((result < x) && (result != 0))
result <<= 1;
return result;
}这是相对有效的,在数据类型中,每位数最多需要一次迭代(例如,32位整数)。
这将返回正确的2的幂,或零的错误(如果输入数字为零,或结果不能表示在数据类型)。
您可以在以下程序中看到它的作用:
#include <stdio.h>
#include <limits.h>
unsigned int fn (unsigned int x) {
if (x == 0) return 0;
unsigned int result = 1;
while ((result < x) && (result != 0))
result <<= 1;
return result;
}
int main (void) {
printf ("%u -> %u\n\n", 0, fn(0));
for (unsigned int i = 1; i < 20; i++)
printf ("%u -> %u\n", i, fn(i));
printf ("\n%u -> %u\n", UINT_MAX, fn(UINT_MAX));
return 0;
}其中产出:
0 -> 0
1 -> 1
2 -> 2
3 -> 4
4 -> 4
5 -> 8
6 -> 8
7 -> 8
8 -> 8
9 -> 16
10 -> 16
11 -> 16
12 -> 16
13 -> 16
14 -> 16
15 -> 16
16 -> 16
17 -> 32
18 -> 32
19 -> 32
4294967295 -> 0https://stackoverflow.com/questions/30496082
复制相似问题