从字节内联重新组装浮点数
我正在使用 HiTech PICC32 开发 PIC32MX 系列微处理器,但我认为这个问题对于任何懂 C 语言的人来说都是足够普遍的。(这几乎相当于 C90,其中 sizeof(int) = sizeof(long) = sizeof(float ) = 4.)
假设我读取了代表 float
的 4 字节数据字。我可以使用以下命令快速将其转换为实际浮点值:
#define FLOAT_FROM_WORD(WORD_VALUE) (*((float*) &(WORD_VALUE)))
但这仅适用于左值。例如,我不能在函数返回值上使用它,例如:
FLOAT_FROM_WORD(eeprom_read_word(addr));
是否有一种简短而甜蜜的方法来内联执行此操作,即无需函数调用或临时变量?老实说,我没有充分的理由避免函数调用或额外的 var,但这让我很烦恼。一定有一种方式我失踪了。
补充:我没有意识到WORD
实际上是一个常见的typedef。我更改了宏参数的名称以避免混淆。
I'm working with HiTech PICC32 on the PIC32MX series of microprocessors, but I think this question is general enough for anyone knowledgable in C. (This is almost equivalent to C90, with sizeof(int) = sizeof(long) = sizeof(float) = 4.)
Let's say I read a 4-byte word of data that represents a float
. I can quickly convert it to its actual float value with:
#define FLOAT_FROM_WORD(WORD_VALUE) (*((float*) &(WORD_VALUE)))
But this only works for lvalues. I can't, for example, use this on a function return value like:
FLOAT_FROM_WORD(eeprom_read_word(addr));
Is there a short and sweet way to do this inline, i.e. without a function call or temp variable? To be honest, there's no HUGE reason for me to avoid a function call or extra var, but it's bugging me. There must be a way I'm missing.
Added: I didn't realise that WORD
was actually a common typedef. I've changed the name of the macro argument to avoid confusion.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您可以以其他方式运行该技巧以获得返回值
或
或如 R Samuel Klatchko 建议的那样
You can run the trick the other way for return values
or
or as R Samuel Klatchko suggests
如果这是 GCC,你可以这样做:
哇。可怕。但用法很好:
我敢打赌你的编译器既不支持
typeof
运算符,也不支持 GCC 所做的union
转换,因为两者都不是标准行为,但在关闭时-你的编译器可以进行union
转换的机会,这就是你的答案。修改为不使用typeof
:当然,这忽略了当您使用两种不同大小的类型时会发生什么问题,但更接近“您想要的”,即返回一个简单的宏过滤器值,而不是采用额外的参数。该版本采用的额外参数只是为了通用。
如果您的编译器不支持 Union 转换(这是一个简洁但不可移植的技巧),那么就无法按照“您想要的方式”执行此操作,并且其他答案已经得到它。
If this were GCC, you could do this:
Wow. Hideous. But the usage is nice:
I bet your compiler doesn't support either the
typeof
operator nor theunion
casting that GCC does, since neither are standard behavior, but in the off-chance that your compiler can dounion
casting, that is your answer. Modified not to usetypeof
:Of course, this ignores the issue of what happens when you use two types of different sizes, but is closer to "what you want," i.e. a simple macro filter that returns a value, instead of taking an extra parameter. The extra parameters this version takes are just for generality.
If your compiler doesn't support
union
casting, which is a neat but non-portable trick, then there is no way to do this the "way you want it," and the other answers have already got it.如果您使用 const 引用,您可以获取临时值的地址:
但这在 c :(
(c 没有引用对吧?在 Visual C++ 中工作)中
不起作用,正如其他人所说,无论是内联函数或者定义中的临时变量,编译器会将其优化掉。
you can take the address of a temporary value if you use a const reference:
but that won't work in c :(
(c doesn't have references right? works in visual c++)
as others have said, be it an inlined function or a temp in a define, the compiler will optimize it out.
不是真正的答案,更多的是建议。如果您的 FLOAT_FROM_WORD 宏没有 ; ,那么使用起来会更自然,也更灵活。在最后
Not really an answer, more a suggestion. Your FLOAT_FROM_WORD macro will be more natural to use and more flexible if it doesn't have a ; at the end
在您的具体情况下,这可能是不可能的,但升级到 C99 编译器也可以解决您的问题。
C99 具有内联函数,虽然其在参数和返回值方面的作用与普通函数类似,但在这种情况下却提高了效率,并且没有宏的缺点。
It may not be possible in your exact situation, but upgrading to a C99 compiler would solve your problem too.
C99 has inline functions which, while acting like normal functions in parameters and return values, get improved efficiency in exactly this case with none of the drawbacks of macros.