如何在C中有效地计算’y’在2 ^ y = 2 ^ q0 … 2 ^ qn?

前端之家收集整理的这篇文章主要介绍了如何在C中有效地计算’y’在2 ^ y = 2 ^ q0 … 2 ^ qn?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有等式:
2^y = 2^q0 + ... 2^qn

n是任意整数(有任意数量的’q’). ‘q’的值可以大到500,其中2 ^ q无法存储在整数或长变量类型中.由于存储容量问题,我想计算除以下方法之外的’y’:

log2(2^q0 + ... + 2^qn)

我怎样才能在C中有效地计算’y’.无论如何,在’q’上用简单的算术运算来计算’y’?

编辑:’q是非负的,我寻找这个问题的2个版本:’q是整数,’q是双

解决方法

首先排序qis.假设最小值是p,从所有q减去p.你可以检查qis是否形成算术系列,如果你很幸运并且他们形成了这样的系列,你有一个数学捷径,但是否则因为AFAIK没有数学规则来简化log(a1 a2 … ak)最好计算y的方法是这样的:

由于您已经对qis进行了排序,因此您可以以类似动态算法的方式计算sum = 1 2 ^(q1-p)2 ^(q2-p)…(即使用先前的结果来计算下一项).

prev_exp = 0;
prev_term = 1;
this_term = 0;
sum = 1;
// p is prevIoUsly subtracted from q[i]s
for (int i = 1; i < n; ++i) {
  this_term = prev_term * (1 << (q[i] - prev_exp)); // 2 ^ m = (1 << m)
  prev_term = this_term;
  prev_exp = q[i] - prev_exp;
  sum += this_term;
}

y可以计算为y = p log2(sum)

请注意,您还要先对小数字求和.这将有助于浮点精度.

我正在编辑这个答案,添加另一种基于分而治之的算法类型的解决方案,但我无法完成它,但我想如果我将它留在一个隐藏的块(此站点的编辑器命名中的扰流块),有人可以完成关闭或改进这部分答案.随时编辑.

在q [i] s的最大值大于它们的最小值的情况下(即p),你可以使用分而治之算法,递归计算sum1 = 1 2 ^(q [1] -p)…. 2 ^(q [n / 2] -p)和sum2 = 2 ^(q [n / 21] -p)… 2 ^(q [n-1] – p)你可以分解2 ^(q [n / 2 1] -p)这里也.然后你会有:y = p log2(sum1 sum2)= p log2(sum1 2 ^ p’south2′)其中p’是q [n / 2 1] -p.它可以帮助您减少数字.

猜你在找的C&C++相关文章