3

我有一个结构

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:\t"<<x;   // prints 0.1 if it is stored, prints 2.4 if 2.4 is fed

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

我想在 var5 中存储浮点值,例如 0.1、3.4、0.8。但我无法这样做。有人可以帮我解决这个问题吗?

4

5 回答 5

4

您可以通过几个中间步骤完成您的要求。首先将您的 float 转换为 int,然后将该 int 转换为二进制表示。从那里,您可以将结果值分配给您的位字段。该答案仅涉及中间步骤。

此处的信息提供了5.2 float由 表示的背景和佐证01000000101001100110011001100110。可以通过多种不同的方式将浮点数分解为二进制表示。这只是一种实现或表示。反转这个过程(即从二进制回到浮动)需要遵循链接中列出的相同规则集,向后。

注意:字节序也是一个因素,我是在 Windows/Intel 环境中运行的。

这是代码:

#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("\n\nEnter a float number: ");
        scanf("%f", &fNum);
        printf("Enter a double precision number: ");
        scanf("%Lf", &ldFloat);

        newInt = floatToInt(fNum);
        {
            //float
            printf("\nfloat: %6.7f\n", fNum);  
            printf("int: %d\n", newInt);  
            printf("Binary: %s\n\n", byte_to_binary32(newInt));
        }
        longInt = doubleToInt(dpNum);
        {
            //double
            printf("double: %6.16Lf\n", ldFloat);  
            printf("int: %lld\n", longInt);  
            printf("Binary: %s\n\n", 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 '\0'
    b[0] = '\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 '\0'
    b[0] = '\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));   
}

这是结果的图像(针对 32 位和 64 位更新):

在此处输入图像描述

于 2013-09-19T20:35:27.507 回答
3

你不能。浮点值的大小是 32 位,您当然不能将其存储在 var5 可用的 4 位中。其他 28 位是非常必要的。

于 2013-09-19T20:04:14.170 回答
3

var5是一个 4 位无符号整数,可以保存值 0..15(在一个合理的假设下工作,它u32是类似 的同义词unsigned int)。

您不能在其中存储小数值。 0.1并将0.8存储为0; 3.4将存储为3.

如果你真的想要分数,你将不得不弄清楚如何表示它们(定点算术)。

于 2013-09-19T20:04:43.260 回答
2

您不能将双精度(64 位)存储到只有 4 位的字段中。你可以这样做:

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

或者这样

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

  struct1[i].var5 = *(u64*)&x; // reinterpret the double as a memory array of 8 bytes

不推荐第二种方式。

如果要将 64 位存储在 4 位中,请阅读浮点 (IEEE) 的工作原理。http://en.wikipedia.org/wiki/IEEE_floating_point

于 2013-09-19T20:05:58.407 回答
0

您不能将浮点值存储在位域结构中。浮点数必须遵守指定表示的特定标准 (IEEE 754)。这些表示适用于 x86 上的 32 位和 64 位。因此,位字段没有必要的空间来正确表示浮点值..

位域必须是有符号或无符号整数。

于 2013-09-19T20:06:53.483 回答