首页 > 解决方案 > 浮点数和字节数组问题的 C++ 联合

问题描述

我正在开发一个 arduino(基于 AVR 平台),我有一种方法可以接收浮点数并将其写入 EEPROM。我必须将浮点数转换为字节数组才能与 EEPROM 交互。我有两个功能如下:

void WriteFloatToEEPROM(int address, float value) {
    union {
        byte byteVal[4];
        float floatVal;
    } data;

    data.floatVal = value;

    for (int i = 0; i < 4; i++) {
        EEPROM.update(address + i, data.byteVal[i]);
    }   
}

float ReadFloatFromEEPROM(int address) {
    union {
        byte byteVal[4];
        float floatVal;
    } data;

    for (int i = 0; i < 4; i++) {
        uint8_t readValue = EEPROM.read(address + i);

        data.byteVal[i] = readValue;        
    }

    return data.floatVal;
}

当我打印出这个结果时,我得到以下几个例子:

Read value at address 50 for float read 0
Read value at address 51 for float read 0
Read value at address 52 for float read 0
Read value at address 53 for float read 0
    Returned float val for address 50:0.00
Read value at address 90 for float read 0
Read value at address 91 for float read 0
Read value at address 92 for float read 0
Read value at address 93 for float read 160
    Returned float val for address 90:-0.00
Read value at address 130 for float read 44
Read value at address 131 for float read 113
Read value at address 132 for float read 61
Read value at address 133 for float read 138
    Returned float val for address 130:-0.00
Read value at address 170 for float read 0
Read value at address 171 for float read 0
Read value at address 172 for float read 0
Read value at address 173 for float read 0
    Returned float val for address 170:0.00

我是在使用错误的联合/向后写入 EEPROM 还是什么?另外,如果有人有更好的方法来做到这一点,我愿意接受建议。提前致谢

标签: c++avrunions

解决方案


不读取联合的“活动”字段是 UB(未定义行为)。

你必须使用memcpy

void WriteFloatToEEPROM(int address, float value) {
    byte byteVal[sizeof(float)];
    memcpy(byteVal, &value, sizeof(float));

    for (int i = 0; i < sizeof(float); i++) {
        EEPROM.update(address + i, byteVal[i]);
    }   
}

float ReadFloatFromEEPROM(int address) {
    byte byteVal[sizeof(float)];

    for (int i = 0; i < sizeof(float); i++) {
        byteVal[i] = EEPROM.read(address + i);
    }

    float f;
    memcpy(&f, byteVal, sizeof(float));
    return f;
}

推荐阅读