给定一个2的幂的整数(2 ^ n),我想找出n,使用对数的索引值。查找索引的公式为:log(number)/ log(2)。以下是代码段:
unsigned long int a;
double apower;
apower = log((double)a) / log((double)2);
我发现'apower'的值在a的某个大值上是错误的,我不知道值,因为我的代码在提交之后失败了。为什么会这样?有铸造问题吗?
以下是整个代码段:
int count = 0;
unsigned long int a,b;
double apower,bpower;
apower = log((double)a) / log((double)2);
bpower = log((double)b) / log((double)2);
count = abs(apower - bpower);
printf("%d\n",count);
a和b的值总是2的幂。所以apower和bpower必须在小数位数为00。这就是为什么count的值将是int(%d)。 我只是想知道Logarithm的行为。
答案 0 :(得分:5)
我只回答了你的一半问题,因为没有必要使用日志来解决这个问题。一个简单的方法是使用它:
unsigned long long a = 0x8000000000000000ULL;
int n = 0;
while (a >>= 1) n++;
printf("%d\n", n);
输出:
63
转换为日志和分区可能会导致重要性丢失,在这种情况下,您应该使用round
。你使用“提交”这个词,这是一个失败的在线挑战?你究竟打印了什么? (在这种情况下)63.000000
?这将来自默认格式%f
。
答案 1 :(得分:4)
为什么不利用log2存储在double的指数字段中这一事实呢? :)
unsigned long long a = 0x8000000000000000ULL;
union {
double d;
unsigned long long l;
} u;
u.d = a;
int apower = (u.l >> 52) - 1023;
printf("%d\n", apower);
输出:
63
这假设无符号长long和双精度是64位并且输入是> 0
答案 2 :(得分:1)
使用double
数学时,日志结果或商可能不是数学结果,而是1(或2)下一个可表示的double
。
计算log()
仅返回log(0)
的精确数学结果,所有其他数学结果都是不合理的。所有double
都是合理的。
这可能会导致像29.999999这样的答案...,保存为int
为29。
推荐使用整数数学
int mylog2(unsigned long x) {
int y = 0;
#if (ULONG_MAX>>16 > 1lu<<16)
if (x >= 1lu<<32) { x >>= 32; y += 32;
#endif
if (x >= 1lu<<16) { x >>= 16; y += 16; }
if (x >= 1lu<<8) { x >>= 8; y += 8; }
if (x >= 1lu<<4) { x >>= 4; y += 4; }
if (x >= 1lu<<2) { x >>= 2; y += 2; }
if (x >= 1lu<<1) { x >>= 1; y += 1; }
return y;
}