c便携式转换长到双
作者:互联网
我需要将长的代表位准确地转换为双精度,并且我的解决方案应可移植到不同的体系结构中(因为g和clang woulf都很棒,所以它们在所有编译器中都可以成为标准).
我正在写一个快速近似值,用于计算this question answers中建议的exp函数.
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将多头转换为双倍.我面临的问题是,在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的大小等于或小于移位参数(表明long和double的大小可能不相同)
我是在做错什么吗?和/或有没有更好的方法来解决这个问题,使其兼容性更好?
解决方法:
首先,使用“ 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存储原始十六进制.无需检查尺寸,一切皆可移植.
标签:c,long-integer,bit-manipulation,double 来源: https://codeday.me/bug/20191013/1910947.html