gpt4 book ai didi

c - C中浮点型整数值

转载 作者:太空狗 更新时间:2023-10-29 16:46:10 25 4
gpt4 key购买 nike

#include<stdio.h>
int main()
{
float a;
printf("Enter a number:");
scanf("%f",&a);
printf("%d",a);
return 0;
}

我在 Ubuntu 中使用 gcc 运行程序。对于值(value)观——

          3.3 it gives value 1610612736 
3.4 it gives value 1073741824
3.5 it gives value 0
3.6 it gives value -1073741824
4 it gives value 0
5 it gives value 0

发生了什么事?为什么打印这些值?我是故意这样做的,但想了解为什么会这样。感谢详细信息!

最佳答案

printf 函数不知道您传入的格式类型,因为那部分是可变的。

int printf(const char* format, ...);
// ^^^

在 C 标准中,传递一个 float 将被自动提升为一个 double (C11§6.5.2.2/6),并且在调用方。

printf 中,因为它不知道那个 ... 东西的类型 (§6.7.6.3/9),所以它必须使用来自别处——格式字符串。由于您已经传递了 "%d",它告诉函数需要一个 int

根据 C 标准,这会导致未定义的行为 (§7.21.6.1/8–9),其中包括打印一些奇怪数字的可能性,故事结束。

但到底发生了什么?在大多数平台中,double 表示为“IEEE 754 binary64”格式,float binary32格式。您输入的数字将转换为 float ,只有 23 位有效,这意味着数字将近似如下:

3.3 ~ (0b1.10100110011001100110011) × 2¹  (actually: 3.2999999523162842...)
3.4 ~ (0b1.10110011001100110011010) × 2¹ (actually: 3.4000000953674316...)
3.5 = (0b1.11 ) × 2¹ (actually: 3.5)
3.6 ~ (0b1.11001100110011001100110) × 2¹ (actually: 3.5999999046325684...)
4 = (0b1 ) × 2² (actually: 4)
5 = (0b1.01 ) × 2² (actually: 5)

现在我们将其转换为 double,它具有 53 位有效位,我们必须在这些数字的末尾插入 30 个二进制“0”,以产生例如

3.299999952316284 = 0b1.10100110011001100110011000000000000000000000000000000 ×2¹

这些主要是推导出那些数字的实际表示,分别是:

3.3 → 400A6666 60000000
3.4 → 400B3333 40000000
3.5 → 400C0000 00000000
3.6 → 400CCCCC C0000000
4 → 40100000 00000000
5 → 40140000 00000000

我推荐使用 http://www.binaryconvert.com/convert_double.html看看这如何分解为 ±m × 2e 格式。

无论如何,我假设您的系统在正常设置下是 x86/x86_64/ARM,这意味着数字是使用 little-endian format 在内存中布局的, 所以传递的参数就像

 byte
#0 #1 ... #4 ... #8 ....
+----+----+----+----+ +----+----+----+----+----+----+----+----+
| 08 | 10 | 02 | 00 | | 00 | 00 | 00 | 60 | 66 | 66 | 0A | 40 | ....
+----+----+----+----+ +----+----+----+----+----+----+----+----+
address of "%d" content of 3.299999952316284
(just an example)

printf里面,它消费格式字符串"%d",解析它,然后发现需要一个int因为 %d,所以从可变输入中取出 4 个字节,即:

 byte
#0 #1 ... #4 ... #8 ....
+ - -+ - -+ - -+ - -+ +====+====+====+====+ - -+ - -+ - -+ - -+
: 08 : 10 : 02 : 00 : | 00 | 00 | 00 | 60 | 66 : 66 : 0A : 40 : ....
+ - -+ - -+ - -+ - -+ +====+====+====+====+ - -+ - -+ - -+ - -+
address of "%d" ~~~~~~~~~~~~~~~~~~~
this, as an 'int'

因此,printf 将收到 0x60000000,并将其显示为十进制整数,即 1610612736,这就是您看到该结果的原因。其他数字可以类似解释。

3.3 → ... 60000000 = 1610612736
3.4 → ... 40000000 = 1073741824
3.5 → ... 00000000 = 0
3.6 → ... C0000000 = -1073741824 (note 2's complement)
4 → ... 00000000 = 0
5 → ... 00000000 = 0

关于c - C中浮点型整数值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8671505/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com