Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
895 views
in Technique[技术] by (71.8m points)

c++ - Unable to save a float value to a bitfield structure

I have a structure

struct {
   u32 var1 :7;
   u32 var2 :4;
   u32 var3 :4;
   u32 var4 :1;
   u32 var5 :4;
   u32 var6 :7;
   u32 var7 :4;
   u32 var8 :1;
        } my_struct;

my_struct struct1[10];

for(int i=0;i<10; i++)
  {
    // left some portion
    struct1[i].var5= x;// where x is a float value retrieved from a database with sqlapi++ asDouble()

    cout<<"Value of x from db is:"<<x;   // prints 0.1 if it is stored, prints 2.4 if 2.4 is fed

    cout<<"Value of x stored in struct1 is:"<<struct1[i].var5;   // prints 0 instead of 0.1, prints 2 instead of 2.4
  }

I want to store floating point values like 0.1, 3.4, 0.8 in var5. But i am unable to do so. Can somebody help me how could i fix this problem?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You can do what you ask with a few intermediate steps. First convert your float to an int, then convert that int into a binary representation. From there, you can assign the resultant values to your bit field. This answer only addresses the intermediate steps.

The information here provides background and corroboration that 5.2 float is represented by 01000000101001100110011001100110. Decomposing a float into a binary representation can be done many different ways. This is only one implementation or representation. Reversing this process (i.e. going from binary back to float) would require following the same set of rules laid out in the link, backwards.

Note: endian is also a factor, I ran this in Windows/Intel environment.

Here is the code:

#include <stdio.h>      /* printf */
#include <stdlib.h>     /* strtol */

const char *byte_to_binary32(long int x);
const char *byte_to_binary64(__int64 x);
int floatToInt(float a);
__int64 doubleToInt(double a);

int main(void)
{
     long lVal, newInt;
     __int64 longInt;
    int i, len, array[65];
    int len1, len2, len3, len4, len5, len6;
    char buf[100];
    char quit[]={" "};
    float fNum= 5.2;
    double dpNum= 5.2;
    long double ldFloat;

    while(quit[0] != 'q')
    {
        printf("

Enter a float number: ");
        scanf("%f", &fNum);
        printf("Enter a double precision number: ");
        scanf("%Lf", &ldFloat);

        newInt = floatToInt(fNum);
        {
            //float
            printf("
float: %6.7f
", fNum);  
            printf("int: %d
", newInt);  
            printf("Binary: %s

", byte_to_binary32(newInt));
        }
        longInt = doubleToInt(dpNum);
        {
            //double
            printf("double: %6.16Lf
", ldFloat);  
            printf("int: %lld
", longInt);  
            printf("Binary: %s

", byte_to_binary64(longInt));  
            /* byte to binary string */
            sprintf(buf,"%s", byte_to_binary64(longInt));
        }
        len = strlen(buf);
        for(i=0;i<len;i++)
        {   //store binary digits into an array.
            array[i] = (buf[i]-'0');    
        }
        //Now you have an array of integers, either '1' or '0'
        //you can use this to populate your bit field, but you will
        //need more fields than you currently have.

        printf("Enter any key to continue or 'q' to exit.");
        scanf("%s", quit);
    }
    return 0;
}

const char *byte_to_binary32(long x)
{
    static char b[33]; // bits plus ''
    b[0] = '';
    char *p = b;  

    unsigned __int64 z;
    for (z = 2147483648; z > 0; z >>= 1)       //2^32
    {
        *p++ = (x & z) ? '1' : '0';
    }
    return b;
}
const char *byte_to_binary64(__int64 x)
{
    static char b[65]; // bits plus ''
    b[0] = '';
    char *p = b;  

    unsigned __int64 z;
    for (z = 9223372036854775808; z > 0; z >>= 1)       //2^64
    {
        *p++ = (x & z) ? '1' : '0';
    }
    return b;
}

int floatToInt(float a)
{
    return (*((int*)&a));   
}

__int64 doubleToInt(double a)
{
    return (*((__int64*)&a));   
}

Here is an image of the results (updated for 32 and 64bit):

enter image description here


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...