繁体   English   中英

C-将两个uint32_t合并为一个double

[英]C - combine two uint32_t to a double

嗨,我正在研究两种协议之间的套接字转换。 我从二进制文件中读取并将解析的标头存储到uint32_t类型的数组中。 然后,我从数组中获取字段并将其转换为相应的类型。 到目前为止,从uint32_t / int32_t / uint16_tint32_t可以正常工作。

但是,当尝试合并两个uint32_t(一个接一个追加)然后将这64位长数据转换为双精度数据时,我得到各种错误的输出。

作为C编程的新手,我正在努力使用double / float表示法的计算机方法。

基本上我想要做的是:在不改变两个位模式uint32_t 康卡斯特 串接一前一后,使64位数据,然后将数据转换为double 最重要的是不要更改位模式,因为该位流的该部分应该是double

以下是代码的一部分:

uint32_t* buffer = (uint32_t*) malloc (arraySize * sizeof(uint32_t));

...

double outputSampleRate = ((union { double i; double outputSampleRate; })
    { .i = ((uint64_t)buffer[6] << 32 | (uint64_t)buffer[7])}).outputSampleRate;

输入文件中的数据:

35.5

我的代码后的值:

4630192998146113536.000000

此外,还有更好的方法来处理套接字标头解析吗?

您的联合定义不正确,您希望将i定义为uint64_t

double outputSampleRate = ((union { uint64_t i; double d; })
    { .i = ((uint64_t)buffer[6] << 32 | (uint64_t)buffer[7])}).d;

您可能还遇到了字节序问题。 试试小尾数法:

double outputSampleRate = ((union { unt64_t i; double d; })
    { .i = ((uint64_t)buffer[7] << 32) | (uint64_t)buffer[6]}).d;

C标准实际上支持通过union重新解释表示形式的位,这称为类型调整。 如果这些位表示目标类型的陷阱值,则不能保证工作。

您可以尝试其他强制转换和技巧:测试运气并使用指针强制转换:

double outputSampleRate = *(uint64_t*)&buffer[6];

强制类型调整的另一种方法是使用memcpy函数:

double outputSampleRate;
uint64_t temp = ((uint64_t)buffer[7] << 32) | (uint64_t)buffer[6];
memcpy(&outputSampleRate, &temp, sizeof(outputSampleRate));

或者简单地:

double outputSampleRate;
memcpy(&outputSampleRate, &buffer[6], sizeof(outputSampleRate));

但是,尽管我在生产代码中已经看到了上述两种情况的某些实例,但它似乎也不能保证能正常工作。

通过并集重新解释位模式要求并集元素具有正确的类型。 您的并集具有两个doubles ,因此当您从其中一个读取时,它将具有与另一个相同的值。 uint32_tdouble的转换将是保留数值结果的转换,解释“垃圾”,实际上只是将double重新解释为整数。 您还需要使用正确的字节顺序(低位字优先还是高位字优先?),最简单的方法是完全避免位移位。

double outputSampleRate = ((union { uint32_t i[2]; double d; })
    { .i = { buffer[6], buffer[7] } }).d;

您可以使用uint64_t i但是...为什么要打扰?

您也可以使用memcpy()复制字节...

double outputSampleRate;
memcpy(&outputSampleRate, &buffer[6], sizeof(outputSampleRate));

通常需要注意以下几点:尽管这些解决方案相对可移植,但它们并未考虑字节顺序问题,并且它们无法在违反您的假设(例如, double大小)的系统上工作,但是进行这些假设通常是安全的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM