c改变double的指数

时间:2014-09-07 15:17:07

标签: c double-precision exponent

假设我有double a = 0.3;。如何在不使用pow()之类的数学函数或手动相乘的情况下更改变量的指数。

我猜我必须使用指针访问变量的内存地址,找到指数并手动更改它。但是我怎么做到这一点?

请注意,这是在8位系统上,我试图找到一种更快的方法来将数字乘以 10 ^ 12 10 ^ 9 10 ^ 6 10 ^ 3

祝你好运!

3 个答案:

答案 0 :(得分:2)

将数字乘以10相当于

  • a)将原始数字乘以2
  • b)将原始数字乘以8
  • c)添加(a)和(b)的结果。

这是有效的,因为它是二进制1010

因此,一种方法是增加指数(对于(a)),将3加到指数(对于(b)),然后加上结果。

要乘以10 ^ n,重复上述n次。或者计算出1,000,1,000,000等的二进制表示,并添加相关的1。你可以通过注意1000例如1024(例如)1024到16 - 8,即

来使事情变得更容易。
  • a)将10添加到原始的指数乘以1024
  • b)将4添加到原始的指数中乘以16
  • c)将3添加到原始的指数乘以8
  • d)从(a)减去(b)和(c)得到答案。

同样,您可以多次执行此操作10 ^ 6,10 ^ 9等。

对于快速逼近和n的倍数为3的倍数,只需向指数加上10n / 3(为1024~ = 1000)

答案 1 :(得分:2)

请注意a*10^3 = a*1000 = a*1024 - a*16 - a*8 = a*2^10 - a*2^4 - a*2^3

所以你可以按如下方式计算a*10^3

  • 将11个指数位读入int exp

  • 将52个小数位读入double frac

  • double x为指数计算exp+10,将frac作为分数计算

  • double y为指数计算exp+4,将frac作为分数计算

  • double z为指数计算exp+3,将frac作为分数计算

  • 将输出计算为x-y-z,如果a < 0

  • ,请勿忘记添加符号位

您可以对其他选项使用类似的方法(a*10^6a*10^9a*10^12)...


以下是如何在&#34;清洁&#34;方式:

double MulBy1000(double a)
{
    double x = a;
    double y = a;
    double z = a;

    unsigned long long* px = (unsigned long long*)&x;
    unsigned long long* py = (unsigned long long*)&y;
    unsigned long long* pz = (unsigned long long*)&z;

    *px += 10ULL << 52;
    *py +=  4ULL << 52;
    *pz +=  3ULL << 52;

    return x - y - z;
}

请注意,我不确定此代码是否符合严格别名规则。

答案 2 :(得分:1)

有趣的是一个简单的递归解决方案。

double ScalePower10(double x, unsigned power) {
    if (power <= 1) {
      if (power == 0) return x;
      return x * 10.0;
    }
    double y = ScalePower10(x, power/2);
    y = y*y;
    if (power%2) y *= 10.0;
    return y;
  }