给定2 ^ n,使用对数找到n

时间:2015-09-06 17:56:34

标签: c math

给定一个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的行为。

3 个答案:

答案 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;
}