假设我有double a = 0.3;
。如何在不使用pow()
之类的数学函数或手动相乘的情况下更改变量的指数。
我猜我必须使用指针访问变量的内存地址,找到指数并手动更改它。但是我怎么做到这一点?
请注意,这是在8位系统上,我试图找到一种更快的方法来将数字乘以 10 ^ 12 , 10 ^ 9 , 10 ^ 6 或 10 ^ 3 。
祝你好运!
答案 0 :(得分:2)
将数字乘以10相当于
这是有效的,因为它是二进制1010
。
因此,一种方法是增加指数(对于(a)),将3加到指数(对于(b)),然后加上结果。
要乘以10 ^ n,重复上述n次。或者计算出1,000,1,000,000等的二进制表示,并添加相关的1。你可以通过注意1000例如1024(例如)1024到16 - 8,即
来使事情变得更容易。同样,您可以多次执行此操作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^6
,a*10^9
和a*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;
}