【问题标题】:Unexpected double value output when using printf使用 printf 时出现意外的双值输出
【发布时间】:2021-02-07 07:58:42
【问题描述】:
#include <stdio.h>
int main()
{
    double  a=7.1;
    printf("%d",a);
    return 0;
}

输出:

1717986918

当我编写这个程序并使用签名格式说明符到方法printf() 时。为什么我会得到这个值?

【问题讨论】:

  • 使用转换说明符"%d" 打印double 值是未定义的行为。什么事情都可能发生。例如,您的程序可能会崩溃...或格式化您的硬盘驱动器...或鼻守护程序可能会出现(另一个选项是您的程序将双精度值7.1 的位序列解释为整数的位序列1717986918 忽略任何剩余位(如果有)
  • 所以%f%lf 说明符就是您所需要的。
  • 使用编译器警告标志总是一个好主意。

标签: c function integer signed


【解决方案1】:

这是format specifier 的问题。
使用"%d",编译器被告知正在打印的数据类型是int,但变量是float,导致undefined behavior,在这种情况下,值1717986918

float 类型的格式说明符是 "%f",而不是 "%d"

改变这个:

printf("%d",a);

到这里:

printf("%f",a);

如果您在编译器设置中使用-Wall 或等效项进行编译,则会发出警告通知您。

【讨论】:

    【解决方案2】:

    您的代码具有未定义的行为。它没有定义你的代码的输出应该是什么,就任何程序员而言,你的代码应该是spawns nasal demons

    为什么在我的 Cprogram 中得到这个输出?

    假设很多关于你的计算机和编译器实现,例如你的编译器使用 IEEE754 标准来表示浮点数,int 的大小是 4 个字节,你的计算机使用小端。根据this site,双精度数7.1 在表示为IEEE754 双精度数时存储为8 个字节作为0x401C666666666666 数。然后这些字节作为可变参数传递给printf。由于架构参数的传递方式,从该数字中提取的最低有效 4 个字节用于 printf %d 格式说明符,这导致打印 0x66666666 数字的基数 10 表示,即 1717986918

    【讨论】:

      猜你喜欢
      • 2013-11-07
      • 2021-09-28
      • 1970-01-01
      • 1970-01-01
      • 2020-07-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多