c ++便携式转换为long to double

时间:2013-11-07 18:23:44

标签: c++ double bit-manipulation long-integer

我需要准确地将长代表位转换为double,并且我的解决方案应该可以移植到不同的架构(能够成为编译器的标准,因为g ++和clang ++也很棒)。

我正在编写快速近似来计算exp函数,如this question answers中所述。

double fast_exp(double val)
{
    double result = 0;

    unsigned long temp = (unsigned long)(1512775 * val + 1072632447);
    /* to convert from long bits to double,
   but must check if they have the same size... */
    temp = temp << 32;
    memcpy(&result, &temp, sizeof(temp));

    return result;
}

我正在使用here找到的建议将long转换为double。我面临的问题是,虽然我在OS X下使用clang ++和libc ++获得了[-5,5]中int值的以下结果:

0.00675211846828461
0.0183005779981613
0.0504353642463684
0.132078289985657
0.37483024597168
0.971007823944092
2.7694206237793
7.30961990356445
20.3215942382812
54.8094177246094
147.902587890625

我总是在Ubuntu下使用clang ++(3.4,相同版本)和libstd ++获得0。那里的编译器甚至告诉我(通过警告)移位操作可能有问题,因为long的大小等于或小于移位参数(表示longs和double可能大小不同)

我做错了什么和/或是否有更好的方法来解决问题,尽可能更兼容?

1 个答案:

答案 0 :(得分:4)

首先,使用“long”不可移植。使用stdint.h中的固定长度整数类型。这将减少检查相同大小的需要,因为您将知道整数的大小。

您收到警告的原因是32位整数左移32位是未定义的行为。 What's bad about shifting a 32-bit variable 32 bits?

另请参阅此答案:Is it safe to assume sizeof(double) >= sizeof(void*)? 应该可以安全地假设double是64位,然后您可以使用uint64_t来存储原始十六进制。无需检查尺寸,一切都是便携式的。