可以将 unsigned int 位值复制为浮点数,但浮点值未正确返回给调用者函数 [英] Could copy unsigned int bit values as float but float value not returned to the caller function correctly

查看:26
本文介绍了可以将 unsigned int 位值复制为浮点数,但浮点值未正确返回给调用者函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

In the below code, I have bits correct (it was originally bits<float> type in C++ program, but I just used uint32 in this C program.). I want to use the bits as the ieee754 float value. Assigning just float_var = int_val won't do it because it interprets the value and casts to float. I want to just use the bit values as floating point values.

    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;

部分程序运行结果:

ff = 3.140000
hh = 4248
bits = 40490000
out = 40092000

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

There must be something basic I don't know. For your information, above run is turning float 3.14 to half-precision and back to single precision and I printed the intermediate values. 0x4248 is in half-precision 3.140625 and bits 0x40490000 is in single-precision also 3.140625, so I just need to return it as float.

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

ADD : After reading comments and answers, I did some experiment and found that the single-float value is seen correct inside the function(using type punning using pointer, or using union), but when it is returned to the calling function, it is not printed correctly. method 0 ~ 3 all don't work. Inline function or not doesn't make any difference. There maybe another fault in our system (an embeded, bare-metal) but hope somebody could tell me what might be wrong here.(I am using part of C++ program in a C program here). (The ldexp, ldexpf didn't work).

== half.h ==

== half.h ==

typedef unsigned short uint16;
typedef unsigned short half;
extern uint16 float2half_impl(float value);
extern float half2float_impl(half value);

== test4.c ==

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

== half.c ==

== 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
        }

推荐答案

这个:

out = *(float *)&bits;

允许您将 bits 作为 float 读取,而无需使用指针魔法进行任何显式或隐式转换.

Allows you to read bits as a float without any explicit or implicit conversion by using pointer magic.

但是请注意,endinaness 可能会让您在这样做时有点受骗(就像memcpy() 也可以,所以如果它对你有用,这个方法也应该可以用,但请记住,这可以从架构到架构不同.

Notice, however, that endinaness might get you a bit screwed doing this (just like memcpy() would too, so if it worked for you this method should work too, but keep in mind that this can change from architecture to architecture).

这篇关于可以将 unsigned int 位值复制为浮点数,但浮点值未正确返回给调用者函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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