我使用了for循环来查找给定数字的对数。
int g = 0, m, diff = 10;
for(j = 0; g <= diff; j++)
{
g = pow(2, j);
}
m = j - 2;
cout << m;
它给出2的幂,其中g
是小于diff
的数字。
我尝试了log的基数变化定理,以找到数字的反对数,如下所示:
m = log(diff) / log(2);
没有for循环,但是在这种情况下,只要数字是2的精确倍数(例如8),那么答案就是2而不是3。
在程序中使用for循环这样做超出了时间限制。
是否有更短且可靠的方法?
答案 0 :(得分:0)
使用整数算术并逐步建立幂。例如:
#include <iostream>
using namespace std;
int main()
{
for (int diff = 1; diff < 129; diff += 5)
{
int p = 1;
int j;
for (j = 0; p <= diff; j++)
{
p *= 2;
}
cout << diff << " = " << (j - 1) << '\n';
}
}
示例输出:
1 = 0
6 = 2
11 = 3
16 = 4
21 = 4
26 = 4
31 = 4
36 = 5
41 = 5
46 = 5
51 = 5
56 = 5
61 = 5
66 = 6
71 = 6
76 = 6
81 = 6
86 = 6
91 = 6
96 = 6
101 = 6
106 = 6
111 = 6
116 = 6
121 = 6
126 = 6
另一种测试策略可以测试边界:
#include <iostream>
using namespace std;
int main()
{
int diff[] = { 1, 2, 3, 4, 5, 7, 8, 9, 15, 16, 17, 31, 32, 33, 63, 64, 65 };
int size = sizeof(diff) / sizeof(diff[0]);
for (int i = 0; i < size; i++)
{
int p = 1;
int j;
for (j = 0; p <= diff[i]; j++)
{
p *= 2;
}
cout << diff[i] << " = " << (j - 1) << '\n';
}
}
示例输出:
1 = 0
2 = 1
3 = 1
4 = 2
5 = 2
7 = 2
8 = 3
9 = 3
15 = 3
16 = 4
17 = 4
31 = 4
32 = 5
33 = 5
63 = 5
64 = 6
65 = 6
很显然,测试循环的内部应该包装到antilog 2 函数中-除了打印操作之外。
答案 1 :(得分:0)
这是一个有趣的解决方案,无需循环:
function antilog(int input) {
int pow2 = input - 1;
pow2 |= pow2 >> 16; // turn on all bits < MSB
pow2 |= pow2 >> 8;
pow2 |= pow2 >> 4;
pow2 |= pow2 >> 2;
pow2 |= pow2 >> 1;
pow2++; // get least pow2 >= input
return // construct binary offset of pow2 bit
((pow2 & 0xffff0000) != 0) << 4
| ((pow2 & 0xff00ff00) != 0) << 3
| ((pow2 & 0xf0f0f0f0) != 0) << 2
| ((pow2 & 0xcccccccc) != 0) << 1
| ((pow2 & 0xaaaaaaaa) != 0);
}
其中后半部分改编自bit twiddling hacks的某些部分。 (知道源代码之后,可能还有其他功能比按照您的要求做的要快。
除了解决方案外,还应注意的是,导致您的解决方案缓慢的原因是重复调用pow
,这是一个相对昂贵的函数。因为您正在执行整数算术(而且还要乘以2
,这是每台计算机最喜欢的数字),所以编写如下的循环会更有效:
int g=1,m,diff=10;
for(j = 0; g <= diff && g <<= 1; j++) /* empty */;
m=j-2;
cout<<m;
这是相当可笑的。 int g=1
将g初始化为代码第一次执行您编写的循环主体时所用的值。循环条件g <= diff && g <<= 1
的值为g <= diff
。 (请注意,如果diff >= 1 << (8 * sizeof(int) - 2)
(我们可以在int中存储的2的最大幂)是一个问题。空语句仅允许我们拥有格式正确的for语句(大多数情况下编译器不会抱怨)。