汇编时间浮动包装/打孔 [英] Compile time float packing/punning

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

问题描述

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



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



我的问题是这:我有一些可重新编程的数字数据存储在EEPROM或芯片的程序闪存中。这意味着当我想要存储一个浮点数时,我必须做一些类型的惩罚:

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

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

//在我们使用的任何存储中存储数据的int
void StoreInt(unsigned int data,unsigned int address);

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

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

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

...所以我的默认数组有这些不可破译的值,如:

  const unsigned int DEFAULTS [] = 
{
0x00000001,//某些默认整数值,1
0x3C83126F,//某些默认浮点值0.005
}

(这些实际上采用 X宏构造,但这并没有什么不同。)评论很好,但是有更好的方法吗?能够执行以下操作非常好:

  const unsigned int DEFAULTS [] = 
{
0x00000001,//某些默认整数值,1
COMPILE_TIME_CONVERT(0.005),//某些默认浮点值,0.005
}

...但我完全失去了,我甚至不知道这样的事情是否可行。



注释


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

  2. 我不太在意可移植性,所以实现定义的行为是很好的,未定义的行为不是(我的IDB附录坐在我面前)。

  3. 正如我所知,fas需要编译时转换,因为 DEFAULTS 在全局范围内。如果我错了,请更正我。


解决方案

c $ c> DEFAULTS 数组一个数组 IntFloat 而不是



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

  const IntFloat DEFAULTS [] = 
{
{.intval = 0x00000001},//某些默认整数值,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天全站免登陆