我的浮动值不';与我在C中的值不匹配
我想把一块木板和一颗覆盆子连接起来。 我必须通过modbus向线路板读/写值,但我不能像线路板那样写浮点值 我使用C和Eclipse调试透视图直接查看变量的值。 电路板发送给我0x46C35000,其值应为25000 Dec,但eclipse显示我为1.18720512e+009 当我在这个网站上试用时,我获得了25000英镑 有什么问题吗? 出于测试目的,我使用以下方法:我的浮动值不';与我在C中的值不匹配,c,floating-point,C,Floating Point,我想把一块木板和一颗覆盆子连接起来。 我必须通过modbus向线路板读/写值,但我不能像线路板那样写浮点值 我使用C和Eclipse调试透视图直接查看变量的值。 电路板发送给我0x46C35000,其值应为25000 Dec,但eclipse显示我为1.18720512e+009 当我在这个网站上试用时,我获得了25000英镑 有什么问题吗? 出于测试目的,我使用以下方法: int main(){ while(1){ // To view easily the value in the
int main(){
while(1){ // To view easily the value in the debug perspective
float test = 0x46C35000;
printf("%f\n",test);
}
return 0;
}
谢谢 分配给
float
的常量0x46C35000
将隐式地将int
值1187205120转换为float
,而不是直接将位叠加到IEEE-754浮点格式
对于这类事情,我通常使用union
:
typedef union xFU
{
float f;
uint32_t i;
} FU;
int main()
{
FU foo;
foo.f = 25000.0;
printf("%.8X\n", foo.i);
foo.i = 0x46C35000;
printf("%f\n", foo.f);
return 0;
}
输出:
46C35000
25000.000000
您混淆了逻辑值和内部表示。您的赋值设置值,该值随后为0x46C35000,即1187205120 要设置浮点数的内部表示形式,您需要对浮点数在内存中的表示方式进行一些假设。不过,在通用计算机上,您使用的网站(IEEE 754,32位)上的假设是公平的 要更改内部表示形式,请使用将原始字节复制到浮点中:
// Ensure our assumptions are correct:
#if !defined(__STDC_IEC_559__) && !defined(__GCC_IEC_559)
# error Floating points might not be in IEEE 754/IEC 559 format!
#endif
_Static_assert(sizeof(float) == sizeof(uint32_t), "Floats are not 32 bit numbers");
输出:25000.000000
(这需要uint32\u t
的标题stdint.h
,以及memcpy
的标题string.h
)执行此操作时:
float test = 0x46C35000;
您将值设置为0x46C35000(十进制1187205120),而不是表示法
您可以按如下方式执行所需操作:
union {
uint32_t i;
float f;
} u = { 0x46C35000 };
printf("f=%f\n", u.f);
这可以安全地将无符号32位值解释为
浮点值当您通过地址访问数据时,您可以了解数据在内存中的表示方式:
#include <stdio.h>
int main()
{
float f25000; // totally unused, has exactly same size as `int'
int i = 0x46C35000; // put binary value of 0x46C35000 into `int' (4 bytes representation of integer)
float *faddr; // pointer (address) to float
faddr = (float*)&i; // put address of `i' into `faddr' so `faddr' points to `i' in memory
printf("f=%f\n", *faddr); // print value pointed bu `faddr'
return 0;
}
它所做的是:
将0x46C35000
放入inti
将i
的地址复制到faddr
中,在float
类型的情况下,该地址也是指向内存中数据的地址
打印由faddr
指向的值;将其视为float
类型
您得到的25000.0
0x46C35000
是1187205120,而不是25000。为什么你期望25000?因为对于董事会来说是25000。。。这是一个量表的构造函数值…如果不能将变量视为板,我想知道如何才能将正确的新值发送给它。关于while loop
和它旁边的注释:不要这样做。相反,请正确配置IDE/编辑器,以便在程序以调试模式终止后仍显示程序输出。我不知道,我认为类型“float”修复了表示形式,因此它在printf中应该是相同的……所以你是说我必须做额外的步骤才能将它放在浮点形式下?@Arnaudprintf
打印值,而不是变量的内部表示形式。更迂腐的断言应该是sizeof(float)*CHAR\u BIT==32
或者一个更干净的直接测试可能是sizeof(float)==sizeof(uint32\u t)
@chux我知道有人会这么说,但考虑到CHAR\u BIT
≠ 8会让OP更加困惑。也就是说,您的第二个测试确实更干净。值得注意的是(语言律师除外)编译器可以优化调用memcpy
:确实如此。尽管值得注意的是,如果您使用typedef
struct,您根本不需要为它指定名称。所以这个“结构”允许我使用十六进制值,但在printf中显示为浮点数?它需要两倍的内存量,或者这里有一个我没有看到的魔术吗?@Arnaud请阅读关于联合
如何在C中工作:@Arnaud联合
的每个成员都从相同的内存地址开始,所以联合
的大小是最大成员的大小。它允许您将一种类型的变量重新解释为另一种类型。@Arnaud:没有十六进制值或十进制值。值是一个数字,是抽象的数学实体。有十六进制或十进制数字,我们在其中解释基数中的数字,以找出它们代表的数字。虽然C在数字和类型之间有一些关联(一个整数是否是十六进制可能会影响它是否是无符号的,并且有一个句点会将它标记为浮点),但将一个值赋给一个float
只会将它的值设置为该值;将浮点
的位设置为十六进制数字的表观位不是一条指令。@dbush:联合的大小至少与其最大成员的大小相同。如果较小构件的对齐要求强制填充,则其可能较大且必须较大。
#include <stdio.h>
int main()
{
float f25000; // totally unused, has exactly same size as `int'
int i = 0x46C35000; // put binary value of 0x46C35000 into `int' (4 bytes representation of integer)
float *faddr; // pointer (address) to float
faddr = (float*)&i; // put address of `i' into `faddr' so `faddr' points to `i' in memory
printf("f=%f\n", *faddr); // print value pointed bu `faddr'
return 0;
}
$ gcc -of25000 f25000.c; ./f25000
f=25000.000000