编译时浮包装/双关语 [英] Compile time float packing/punning

查看:130
本文介绍了编译时浮包装/双关语的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

添加我以下的标准是GNU99(C99与GNU扩展,编译器标志 -std = gnu99

我的问题是这样的:我有一个存储无论是在EEPROM或芯片的程序闪存可重新编程的一些数字数据。这意味着,当我想存储一个花车,我必须做一些类型双关语:

 的typedef工会
{
    INT INTVAL;
    浮floatval;
} IntFloat;unsigned int类型float_as_int(浮点FVAL)
{
    IntFloat INTF;
    intf.floatval =未来值;
    返回intf.intval;
}//存储在任何存储,我们正在使用的数据INT
无效StoreInt(unsigned int类型的数据,无符号整型地址);无效StoreFPVal(浮点数据,无符号整型地址)
{
    StoreInt(float_as_int(数据),地址);
}

我还包括缺省值作为编译时间常数的阵列。对于(无符号)的整数值,这是小事,我只是使用整数文字。对于花车,虽然,我必须用这个Python的片段,将它们转换为他们的话再presentation,包括他们在阵列中:

 进口结构
十六进制(struct.unpack(I,struct.pack(F,float_value))[0])

...等我的违约数组有这些难懂的值,如:

  const的无符号整型默认值[] =
{
    00000001,//某些默认整数值,1
    0x3C83126F,//某些默认浮点值,0.005
}

(这实际上采取的形式,<一个href=\"http://stackoverflow.com/questions/2927245/looking-for-a-good-explanation-of-the-table-generation-macro-idiom\">X宏观构造,但这并不在这里有所作为。)评论是好的,但有没有更好的办法?这是巨大的,能够做这样的事情:

  const的无符号整型默认值[] =
{
    00000001,//某些默认整数值,1
    COMPILE_TIME_CONVERT(0.005),//某些默认浮点值,0.005
}

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

备注


  1. 显然不,这是不可能的,是如果属实的可以接受的答案。

  2. 我并不过分在意便携性,所以实现定义的行为是好的,不确定的行为是不是(我有IDB附录坐在我面前)。

  3. 如FAS我所知,这需要一个编译时间转换,因为默认值是在全球范围内。请纠正我,如果我错了这一点。


解决方案

可以让你的默认值阵列 IntFloat 呢?

如果可以的话,的的编译器支持C99,那么你可以这样做:

 常量IntFloat默认值[] =
{
    {.intval = 00000001} //某些默认整数值,1
    {.floatval = 0.005} //某些默认浮点值,0.005
};

I'm writing C for the PIC32MX, compiled with Microchip's PIC32 C compiler (based on GCC 3.4).

Added The standard I'm following is GNU99 (C99 with GNU extensions, compiler flag -std=gnu99)

My problem is this: I have some reprogrammable numeric data that is stored either on EEPROM or in the program flash of the chip. This means that when I want to store a float, I have to do some type punning:

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);
}

I also include default values as an array of compile time constants. For (unsigned) integer values this is trivial, I just use the integer literal. For floats, though, I have to use this Python snippet to convert them to their word representation to include them in the array:

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

...and so my array of defaults has these indecipherable values like:

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

(These actually take the form of X macro constructs, but that doesn't make a difference here.) Commenting is nice, but is there a better way? It's be great to be able to do something like:

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

...but I'm completely at a loss, and I don't even know if such a thing is possible.

Notes

  1. Obviously "no, it isn't possible" is an acceptable answer if true.
  2. I'm not overly concerned about portability, so implementation defined behaviour is fine, undefined behaviour is not (I have the IDB appendix sitting in front of me).
  3. As fas as I'm aware, this needs to be a compile time conversion, since DEFAULTS is in the global scope. Please correct me if I'm wrong about this.

解决方案

Can you make your DEFAULTS array an array of IntFloat instead?

If you can, and your compiler supports C99, then you can do this:

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

这篇关于编译时浮包装/双关语的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆