编译时 float 打包/双关语

标签 c gcc embedded type-punning

我正在为 PIC32MX 编写 C,使用 Microchip 的 PIC32 C 编译器(基于 GCC 3.4)编译。

已添加 我遵循的标准是 GNU99(C99 带有 GNU 扩展,编译器标志 -std=gnu99)

我的问题是:我有一些可重新编程的数字数据,这些数据存储在 EEPROM 或芯片的程序闪存中。这意味着当我想存储一个 float 时,我必须进行一些类型双关:

typedef union
{
    int intval;
    float floatval;
} IntFloat;

unsigned int float_as_int(float fval)
{
    IntFloat intf;
    intf.floatval = fval;
    return intf.intval;
}

// Stores an int of data in whatever storage we're using
void StoreInt(unsigned int data, unsigned int address);

void StoreFPVal(float data, unsigned int address)
{
    StoreInt(float_as_int(data), address);
}

我还将默认值作为编译时常量数组包含在内。对于(无符号)整数值,这是微不足道的,我只使用整数文字。不过,对于 float ,我必须使用这个 Python 片段将它们转换为它们的单词表示形式,以将它们包含在数组中:

import struct
hex(struct.unpack("I", struct.pack("f", float_value))[0])

...因此我的默认值数组具有这些难以辨认的值,例如:

const unsigned int DEFAULTS[] =
{
    0x00000001, // Some default integer value, 1
    0x3C83126F, // Some default float value, 0.005
}

(这些实际上采用 X macro 构造的形式,但这在这里没有什么区别。)注释很好,但是有更好的方法吗?能够做这样的事情真是太好了:

const unsigned int DEFAULTS[] =
{
    0x00000001, // Some default integer value, 1
    COMPILE_TIME_CONVERT(0.005), // Some default float value, 0.005
}

...但是我完全不知所措,我什至不知道这样的事情是否可能。

注意事项

  1. 显然“不,这不可能”是一个可以接受的答案(如果为真)。
  2. 我并不太关心可移植性,因此实现定义的行为很好,未定义的行为则不然(我面前有 IDB 附录)。
  3. 据我所知,这需要进行编译时转换,因为 DEFAULTS 在全局范围内。如果我对此有误,请纠正我。

最佳答案

你能把你的 DEFAULTS 数组改成 IntFloat 数组吗?

如果可以,并且您的编译器支持 C99,那么您可以这样做:

const IntFloat DEFAULTS[] =
{
    { .intval = 0x00000001 }, // Some default integer value, 1
    { .floatval = 0.005 }, // Some default float value, 0.005
};

关于编译时 float 打包/双关语,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2947127/

相关文章:

c - 验证负数不方便

c - 对数组指针自增的疑问

c - 为内联汇编参数打开即时值传播的特定 GCcflags是什么?

linux - 在 CentOS7.4 的 AARCH64 平台上首选哪个 GCC 版本?

c - 使用内联组件绘制像素 VGA

gcc - 从静态库创建共享库时保留所有导出的符号

转换为6位

c - 结构成员的大小

operating-system - 完全可以在没有虚拟内存的情况下运行,只需要物理内存(事实上,大多数嵌入式系统都以这种方式运行)。如何?

c++ - 为 ARM mbed 编译 PicoTCP 时未定义对 pico_dhcp_server_initiate 的引用