繁体   English   中英

如何将 64 位浮点数添加到特定索引处的 unsigned char 数组(C++)

[英]How can I add a 64 bit floating point number to an unsigned char array at specific indexes (C++)

我需要将一个 64 位浮点数添加到特定索引处的unsigned char数组中(例如索引18 )。

unsigned char数组示例:

unsigned char msg[10] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

例如,我想在索引1,2,3,4,5,6,7,8处的无符号字符数组中添加一个像0.084这样的浮点数,它在十六进制(小端)中表示为1B2FDD240681B53F并留下索引09不变。

因此,我希望无符号字符数组msg包含以下内容:

msg = {0x00, 0x1B, 0x2F, 0xDD, 0x24, 0x06, 0x81, 0xB5, 0x3F, 0x00}

到目前为止,我可以使用以下代码获得带有示例浮点值0.084的十六进制表示的std::string ,但我不确定如何将字符串值添加回 unsigned char 数组:

#include <iostream>
#include <sstream> 
#include <iomanip>

using namespace std;

int main()
{
    union udoub
    {
        double d;
        unsigned long long u;
    };

    double dVal = 0.084;
    udoub val;
    val.d = dVal;
    
    std::stringstream ss;
    ss << std::setw(16) << std::setfill('0') << std::hex << val.u << std::endl;
    std::string strValHexString = ss.str();
    
    cout<< strValHexString << std::endl;

    return 0;
}

输出: 3fb5810624dd2f1b

我试图使用std::copy在例如像下面的值从复制std::string到一个unsigned char ,但它似乎并没有做我想做的:

unsigned char ucTmp[2];
std::copy(strValHexString.substr(0,2).begin(), strValHexString.substr(0,2).end(), ucTmp);

寻找 C 或 C++ 解决方案。

将组件字节格式化为十六进制字符串,然后再次读取这些字节是对时间和精力的可怕浪费。 只需使用std::memcpy() (在 C++ 中)或memcpy (在 C 中):

    std::memcpy(&msg[1], &dVal, sizeof(dVal));

这将处理任何所需的指针对齐问题。 但是,它不会根据您的字节顺序进行任何“解释” - 但这应该不是问题,除非您随后在不同平台之间传输该字节数组。

由于从联合的非活动成员读取,您的示例具有未定义的行为。 转换为整数的定义明确的方法:

auto uVal = std::bit_cast<std::uint64_t>(dVal);

现在您拥有整数形式的数据,您可以使用按位运算来提取特定位置的单个八位字节:

msg[1] = (uVal >> 0x0 ) & 0xff;
msg[2] = (uVal >> 0x8 ) & 0xff;
msg[3] = (uVal >> 0x10) & 0xff;
msg[4] = (uVal >> 0x18) & 0xff;
msg[5] = (uVal >> 0x20) & 0xff;
...

这可以压缩成一个循环。

请注意,无论 CPU 的字节序如何,这都以相同的方式工作。 与直接std::memcpy方法不同,数组中的结果顺序将始终是小端顺序,这会导致本机端顺序,这不一定是所有系统上的小端顺序。 但是,如果浮点数和整数使用不同的字节序,那么即使使用这种方法,顺序也不会相同。

暂无
暂无

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

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