无法将浮点值保存到位域结构

我有一个结构

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。 但我无法这样做。 有人可以帮助我如何解决这个问题?

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

您无法在其中存储小数值。 0.10.8将存储为0 ; 3.4将存储为3

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

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

您不能将双(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 

不推荐第二种方式。

如果要以4位存储64位,请了解浮点(IEEE)的工作原理。 http://en.wikipedia.org/wiki/IEEE_floating_point

[编辑] 此答案的代码已更新,包括从浮点或双精度到二进制表示的64位转换。

你可以按照你的要求做,但你必须分步进行。 首先将您的float转换为int,然后将该int转换为二进制表示。

这篇文章使用来自HERE的信息来validation结果。 (5.2由01000000101001100110011001100110表示)。 将浮点分解为二进制表示可以通过许多不同方式完成。 这只是一种实现或表示。 反转这个过程(即从二进制回到浮动)将需要遵循此链接中规定的相同规则集,向后。

注意: endian也是一个因素,我在Windows / Intel环境中运行它。

这是代码:

 #include  /* printf */ #include  /* 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 0; z >>= 1) //2^32 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 = 4294967296; z > 0; z >>= 1) //2^32 for (z = 9223372036854775808; z > 0; z >>= 1) //2^32 { *p++ = (x & z) ? '1' : '0'; } return b; } int floatToInt(float a) { return (*((int*)&a)); } __int64 doubleToInt(double a) { return (*((__int64*)&a)); } 

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

在此处输入图像描述

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

位域冥想是有符号或无符号整数。