gpt4 book ai didi

c++ - AIX 编译器 13.1.3 对 c++ 的双重转换不正确

转载 作者:太空宇宙 更新时间:2023-11-04 12:45:53 28 4
gpt4 key购买 nike

我们将 char* 数组中的数据转换为 double,如下面的函数所示:

double getDouble(const char* szData, const size_t dataLength)
{
double res = 0;
if(dataLength == 8)
{
ub8 doubleData = *(ub8*)(szData);
doubleData = ntohll(doubleData);
double* pDoubleData = (double*)(&doubleData);
res = *pDoubleData;
}
return res;
}

ub8 的大小为 8 字节,unsigned long long。double 值 -1.1512299550195975 转换为 3.6975400899608046。但输入和输出应该相等(等于-1.1512299550195975)。这种情况只发生在 AIX 中。在其他平台上我们得到正确的结果。

我们为我们的项目使用优化级别 O2。如果我将优化级别用作 O1 ,则数据会正确转换。你能帮我吗,你怎么看,为什么转换对于优化级别 O1 是正确的,为什么它对于优化级别 O2 是不正确的?可能我应该在编译中关闭或打开 aix 的某些标志?谢谢。 Aix 编译器版本为 13.1.3。

我们从二进制文件中获取 char 数组格式的 double 值。我们从 oracle 数据库的事务日志中解析数据。而oracle写的,比如double值是'40 0d 94 8f e6 10 3e 93'我们应该把double类型的值转换成'-1,1512299550195975'。但在唯一的 aix 中,我们得到 '3,6975400899608046' 不正确的值

最佳答案

您的实现依赖于未定义的行为,特别是违反了严格的别名规则,正如有人评论的那样。

这就是为什么有时它可以工作(没有优化)有时不能工作的原因。

为避免违反严格别名,您可以使用以下其中一项:

仅在 C 中(不是 C++,更多信息 here):

typedef union swap64{
unsigned long long u64;
double d64;
}swap64;
swap64 s;
memcpy(s.u64, szData, sizeof(swap64));
s.u64=ntohll(s.u64);

//Following line is UB in C++, but not in C:
return s.d64;

或者没有 UB(代码在 C++ 和 C 中均有效):

unsigned long long u64;
double d64;

//Most compilers will remove the memcpy calls and replace them by simpler instructions
memcpy(&u64, szData, sizeof(u64));
u64=ntohll(u64);
memcpy(&d64, &u64, sizeof(u64));

return d64;

关于c++ - AIX 编译器 13.1.3 对 c++ 的双重转换不正确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51634785/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com