我有一个结构
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。但我无法这样做。有人可以帮我解决这个问题吗?
答案 0 :(得分:3)
你做不到。浮点值的大小为32位,您当然无法将其存储在4位var5中。其他28位是非常必要的。
答案 1 :(得分:3)
var5
是一个4位无符号整数,可以保存值0..15(合理假设u32
是unsigned int
之类的同义词。)
您无法在其中存储小数值。 0.1
和0.8
将存储为0
; 3.4
将存储为3
。
如果你真的想要分数,你将不得不弄清楚如何表示它们(定点运算)。
答案 2 :(得分:2)
您可以通过几个中间步骤来完成您的要求。首先将您的float转换为int,然后将该int转换为二进制表示。从那里,您可以将结果值分配给您的位字段。这个答案只涉及中间步骤。
here 信息提供5.2 float
由01000000101001100110011001100110
代表的背景和佐证。将浮点分解为二进制表示可以通过许多不同方式完成。这只是一种实现或表示。颠倒这个过程(即从二进制回到浮动)将需要遵循链接中向后布置的相同规则集。
注意: endian也是一个因素,我在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位更新):
答案 3 :(得分:1)
您不能将双(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
答案 4 :(得分:0)
您不能在位字段结构中存储浮点值。浮点数必须遵守指定表示的特定标准(IEEE 754)。这些表示在x86上为32位和64位。因此,位字段没有足够的空间来正确表示浮点值。
位域冥想是有符号或无符号整数。