在C

时间:2015-11-18 10:30:39

标签: c floating-point

以下程序的输出是否正确?我在X86_64 Windows系统上使用Cygwin64 GCC编译器。该架构是小端。

#include <stdio.h>

int main(int argc, char *argv[])
{
    int i = 0;
    float floatVal = 0x12345678;
    do
    {
        printf("Hello World %f\n", floatVal);
        floatVal++;
        i++;
    } while ( i < 10 );
    return 0;
}

Hello World 305419904.000000
Hello World 305419904.000000
Hello World 305419904.000000
Hello World 305419904.000000
Hello World 305419904.000000
Hello World 305419904.000000
Hello World 305419904.000000
Hello World 305419904.000000
Hello World 305419904.000000
Hello World 305419904.000000

问题1: 然而,这个网站给了我一个完全不同的答案:http://www.binaryconvert.com/result_float.html?hexadecimal=12345678

问题2: 为什么价值不增加?但是,如果我使用double而不是float,则会发生增量。

我做错了什么?

在得到正确答案后编辑:

从unwind获得正确的答案后,我还有一个问题,并在Java中做同样的事情。既然Java,不使用联合,有没有办法从整数到浮点转换方式与C中接受的答案相同。我在这里找到了答案:

How can I get/set individual bits in a float?

2 个答案:

答案 0 :(得分:4)

您期望使用整数文字(0x12345678)来设置float的位,但事实并非如此。

而是获得实际整数(0x12345678305419896十进制);你的代码与它说的完全相同

float floatVal = 305419896;

十六进制数只是一个整数,它的十六进制没有特殊含义。

要做你想做的事,你可能会使用实际的hexadecimal float constant,但这有点复杂。

您可以使用union对其中的位:

const union {
 int integer;
 float real;
} pair = { .integer = 0x12345678 };
float floatVal = pair.real;

请注意,如果大小不匹配,并且(您似乎也知道)特定于字节序,则上述内容未定义。

如果使用%e%g进行打印,您将获得预期的结果:

printf("%g\n", floatVal);

在ideone.com上打印5.69046e-28

答案 1 :(得分:2)

首先,您对整数文字(转换为浮点数)的十六进制和浮点数的十六进制表示感到困惑。 0x12345678 == 305419904

至于使用++的浮点数的增量似乎没有按预期工作 - 这仅仅是由于单精度浮点表示的有限精度。如果您从较小的数字开始,那么您将看到预期的行为:

 float f = 1.0f;  // f = 1.0
 f++;             // f = 2.0

但是在你的例子中:

 float f = 305419904.0f;  // f = 305419904.0
 f++;                     // f = 305419904.0

请注意,使用double会为这种情况提供正确的结果:

 double g = 305419904.0;  // g = 305419904.0
 g++;                     // g = 305419905.0