可以将无符号的int位值复制为float,但float值不会正确返回给调用者函数

Cha*_*Kim 0 c arrays types

在下面的代码中,我有bits正确的(它最初是bits<float>在C++程序中输入的,但我只是uint32在这个C程序中使用过.).我想将这些位用作ieee754 float值.分配只是float_var = int_val不会这样做,因为它解释了值并转换为float.我想只使用位值作为浮点值.

    uint32 bits = mantissa_table[offset_table[value>>10]+(value&0x3FF)] + exponent_table[value>>10];
    ab_printf("bits = %x\n", bits);
    float out;
    //memcpy(&out, &bits, sizeof(float));  // original
    char *outp = &out;
    char *bitsp  = &bits;
   outp[0] = bitsp[0];
   outp[1] = bitsp[1];
   outp[2] = bitsp[2];
   outp[3] = bitsp[3];
    ab_printf("out = %x\n", out);
    return out;
Run Code Online (Sandbox Code Playgroud)

程序运行结果的一部分:

ff = 3.140000
hh = 4248
bits = 40490000
out = 40092000
Run Code Online (Sandbox Code Playgroud)

必须有一些我不知道的基本知识.为了您的信息,上面的运行是将浮动3.14转为半精度并返回单精度,我打印中间值.0x4248是半精度3.140625,位0x40490000也是单精度3.140625,所以我只需要将其返回为float.

ADD:在阅读了注释和答案之后,我做了一些实验,发现在函数内部看到单浮点值是正确的(使用指针或使用union的类型punning),但是当它返回到调用函数时,它是打印不正确.方法0~3都不起作用.内联函数与否没有任何区别.在我们的系统中可能存在另一个错误(嵌入式,裸机),但希望有人可以告诉我这里可能有什么问题.(我在这里使用C程序中的C++程序的一部分).(ldexp,ldexpf不起作用).

== half.h ==

typedef unsigned short uint16;
typedef unsigned short half;
extern uint16 float2half_impl(float value);
extern float half2float_impl(half value);
Run Code Online (Sandbox Code Playgroud)

== test4.c ==

#include "half.h"

int main()
{
float vflt = 3.14;
half vhlf;
float vflt2;

ab_printf("vflt = %f\n", vflt);
vhlf = float2half_impl(vflt);
ab_printf("vhlf = %x\n", *(unsigned short *)&vhlf);
float vflt2 = half2float_impl(vhlf);
ab_printf("received : vflt2 = %f\n", vflt2);
}
Run Code Online (Sandbox Code Playgroud)

== half.c ==

#include "half.h"
....
inline float half2float_impl(uint16 value)
        {
            //typedef bits<float>::type uint32;
            typedef unsigned int uint32;
            static const uint32 mantissa_table[2048] = {
....
            uint32 bits = mantissa_table[offset_table[value>>10]+(value&0x3FF)] + exponent_table[value>>10];
            ab_printf("bits = %x\n", bits);

            float out;

    #define METHOD 3
    #if METHOD == 0
            memcpy(&out, &bits, sizeof(float));
            return out;
    #elif METHOD == 1
        #warning METHOD 1
            ab_printf("xx = %f\n", *(float *)&bits); // prints 3.140625
            return bits;
    #elif METHOD == 2 // prints float ok but return value float prints wrong
        #warning METHOD 2
            union {
                unsigned int ui;
                float xx;
            } aa;
            aa.ui = bits;
            ab_printf("xx = %f\n", aa.xx); // prints 3.140625
            return (float)aa.xx; // but return values prints wrong
    #elif METHOD == 3 // prints float ok but return value float prints wrong
        #warning METHOD 3
            ab_printf("xx = %f\n", *(float *)&bits); // prints 3.140625
            return *(float *)&bits; // but return values prints wrong
    #else
        #warning returning 0
        return 0;
    #endif
        }
Run Code Online (Sandbox Code Playgroud)

Som*_*ude 5

使用工会怎么样?

union uint32_float_union
{
    uint32_t i;
    float    f;
};
Run Code Online (Sandbox Code Playgroud)

然后你可以做类似的事情

union uint32_float_union int_to_float;
int_to_float.i = bits;
printf("float value = %f\n", int_to_float.f);
Run Code Online (Sandbox Code Playgroud)

C规范明确允许使用联合进行类型惩罚.

memcpy你注释掉的方式应该有效,但确实打破了严格的别名.您可以使用字节缓冲区作为中间件:

char buffer[sizeof(float)];
memcpy(buffer, &bits, sizeof(float));

float value;
memcpy(&value, buffer, sizeof(float));
Run Code Online (Sandbox Code Playgroud)

当然,所有这些都要求bits实际上对应于有效值float(包括正确的字节序).