我正在研究一个大规模模拟的高速计算问题。为了加速这个过程,我想做几个优化,其中之一是在没有跳转的几个周期中计算一个双的绝对值。
我的想法是,64位双值用1位符号位、11位指数和52位尾数表示。因此,带有掩码的双值XOR-ed : 10000000 00000000 00000000 00000000将产生所需的结果:
double abs(double x) {
double mask = -0.0e0;
return x^mask;
}现在很明显,没有什么理由需要对双行进行二进制操作,所以编译器自然会抛出一个错误:
error: invalid operands to binary ^ (have ‘double’ and ‘double’)我想知道是否有任何方法使这一工作在一个快速的方式,因为我不希望把整个事情转换成一个字符数组和返回的建议,在其他地方。这会使快速计算的目的落空。
我感谢所有的帮助..。
发布于 2013-12-08 22:29:18
@Artur的变体:
。。使用匹配大小的整数。
。。使用double初始化联合。不是更快,而是更紧。
#include <stdint.h>
double Abs_double(double d) {
union {
double d;
uint64_t u64;
} u = {d};
u.u64 &= ~( (uint64_t) 1 << 63);
return u.d;
}注意:除非分析更快地显示其他解决方案,否则我将继续使用fabs()。
发布于 2013-12-08 19:48:43
还没有检查,但这应该可以完成以下工作:
double abs(double x)
{
long long tmp = *((long long*)&x);
tmp &= ~(1LL << 63);
return *((double*)&tmp);
}更新:
用户评论我的解决方案对上述代码的问题是正确的。这样做应该更好:
double my_abs(double x)
{
union my64bits
{
unsigned long long a;
double b;
};
union my64bits tmp;
tmp.b = x;
tmp.a &= ~(1uLL<<63);
return tmp.b;
}发布于 2013-12-08 19:56:15
double x;
int *p = (int *)&x;
*(p+1) ^= (1 << 31);https://stackoverflow.com/questions/20458125
复制相似问题