4
#include <stdio.h>

union NumericType
{
    float value;
    int intvalue;
}Values;

int main()
{
    Values.value = 1094795585.00;
    printf("%f \n",Values.value);
    return 0;
}

该程序输出为:

1094795648.000000 

谁能解释为什么会这样?为什么浮动的价值Values.value增加了​​?或者我在这里错过了什么?

4

7 回答 7

27

首先,这与使用 a 没有任何关系union

现在,假设你写:

int x = 1.5;
printf("%d\n", x);

会发生什么? 1.5不是整数值,因此它被转换为整数(通过截断),x因此实际上得到了 value 1,这正是打印的内容。

您的示例中也发生了完全相同的事情。

float x = 1094795585.0;
printf("%f\n", x);

1094795585.0不能表示为单精度浮点数,因此它被转换为可表示的值。这通过四舍五入发生。最接近的两个值是:

1094795520 (0x41414100) -- closest `float` smaller than your number
1094795585 (0x41414141) -- your number
1094795648 (0x41414180) -- closest `float` larger than your number

因为您的数字稍微接近较大的值(如果您查看十六进制表示,这更容易看出),它会四舍五入到该值,因此这是存储在x中的值,也就是打印的值。

于 2010-08-05T20:45:10.690 回答
14

浮点数并不像您希望的那样精确。它的有效 24 位尾数仅提供 7-8 位十进制数字的精度。您的示例需要 10 位小数精度。double 具有有效的 53 位尾数,可提供 15-16 位的精度,足以满足您的目的。

于 2010-08-05T20:34:05.823 回答
7

这是因为您的float类型没有显示该数字的精度。使用double.

于 2010-08-05T20:34:38.417 回答
2

浮点数只有 7 位精度 有关详细信息,请参阅此链接: 链接文本

当我这样做时,我得到相同的结果:

int _tmain(int argc, _TCHAR* argv[])
{
    float f = 1094795585.00f; 
    //        1094795648.000000
    printf("%f \n",f); 
    return 0; 
}
于 2010-08-05T20:38:37.977 回答
1

我根本不明白为什么人们使用浮点数 - 它们通常不比双精度数快,并且可能更慢。这段代码:

#include <stdio.h>

union NumericType
{
    double value;
    int intvalue;
}Values;

int main()
{
    Values.value = 1094795585.00;
    printf("%lf \n",Values.value);
    return 0;
}

产生:

1094795585.000000
于 2010-08-05T20:51:46.163 回答
0

默认情况下,带有 %f 的浮点 printf 将在小数点后给出精度 6。如果您想要小数点后 2 位的精度,请使用 %.2f。即使下面给出相同的结果

#include <stdio.h>
union NumericType
{
    float value;
    int intvalue;
}Values;

int main()
{
    Values.value = 1094795585;
    printf("%f \n",Values.value);
    return 0;
}

Result 
./a.out
1094795648.000000
于 2010-08-06T06:37:53.333 回答
0

说十进制数字只会使事情复杂化,因为这是二进制算术。为了解释这一点,我们可以从单精度格式的整数集合开始,其中所有整数都是可表示的。由于单精度格式具有 23+1=24 位精度,这意味着范围是

0 to 2^24-1

这不够好或不够详细,无法解释,所以我将进一步完善它

0 to 2^24-2^0 in steps of 2^0

下一个更高的集合是

0 to 2^25-2^1 in steps of 2^1

下一组是

0 to 2^23-2^-1 in steps of 2^-1

您的号码 1094795585(十六进制的 0x41414141)落在最大值略小于 2^31 = 的范围内。该范围可以详细表示为 0 到 2^31-2^7,步长为 2^7。这是合乎逻辑的,因为 2^31 是 2 的 7 次方大于 24。因此增量也必须是 2 的 7 次方。

查看另一篇文章中提到的“下一个更低”和“下一个更高”值,我们看到它们之间的差异是 128,即 2^7。

这真的没有什么奇怪的、奇怪的、有趣的,甚至没有什么神奇的。它实际上非常清楚而且非常简单。

于 2011-02-24T12:54:05.063 回答