我的浮动值不';与我在C中的值不匹配

我的浮动值不';与我在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

我想把一块木板和一颗覆盆子连接起来。 我必须通过modbus向线路板读/写值,但我不能像线路板那样写浮点值

我使用C和Eclipse调试透视图直接查看变量的值。 电路板发送给我0x46C35000,其值应为25000 Dec,但eclipse显示我为1.18720512e+009

当我在这个网站上试用时,我获得了25000英镑

有什么问题吗? 出于测试目的,我使用以下方法:

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
放入int
i

i
的地址复制到
faddr
中,在
float
类型的情况下,该地址也是指向内存中数据的地址

打印由
faddr
指向的值;将其视为
float
类型


您得到的
25000.0

0x46C35000
是1187205120,而不是25000。为什么你期望25000?因为对于董事会来说是25000。。。这是一个量表的构造函数值…如果不能将变量视为板,我想知道如何才能将正确的新值发送给它。关于
while loop
和它旁边的注释:不要这样做。相反,请正确配置IDE/编辑器,以便在程序以调试模式终止后仍显示程序输出。我不知道,我认为类型“float”修复了表示形式,因此它在printf中应该是相同的……所以你是说我必须做额外的步骤才能将它放在浮点形式下?@Arnaud
printf
打印值,而不是变量的内部表示形式。更迂腐的断言应该是
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