c++ portable conversion of long to double

送分小仙女□ 提交于 2019-12-02 10:16:08

问题


I need to accurately convert a long representing bits to a double and my soluton shall be portable to different architectures (being able to be standard across compilers as g++ and clang++ woulf be great too).

I'm writing a fast approximation for computing the exp function as suggested in 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;
}

and I'm using the suggestion found here to convert the long into a double. The issue I'm facing is that whereas I got the following results for int values in [-5, 5] under OS X with clang++ and libc++:

0.00675211846828461
0.0183005779981613
0.0504353642463684
0.132078289985657
0.37483024597168
0.971007823944092
2.7694206237793
7.30961990356445
20.3215942382812
54.8094177246094
147.902587890625

I always get 0 under Ubuntu with clang++ (3.4, same version) and libstd++. The compiler there even tells me (through a warning) that the shifting operation can be problematic since the long has size equal or less that the shifting parameter (indicating that longs and doubles have not the same size probably)

Am I doing something wrong and/or is there a better way to solve the problem being as more compatible as possible?


回答1:


First off, using "long" isn't portable. Use the fixed length integer types found in stdint.h. This will alleviate the need to check for the same size, since you'll know what size the integer will be.

The reason you are getting a warning is that left shifting 32 bits on the 32 bit intger is undefined behavior. What's bad about shifting a 32-bit variable 32 bits?

Also see this answer: Is it safe to assume sizeof(double) >= sizeof(void*)? It should be safe to assume that a double is 64bits, and then you can use a uint64_t to store the raw hex. No need to check for sizes, and everything is portable.



来源:https://stackoverflow.com/questions/19843704/c-portable-conversion-of-long-to-double

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!