【问题标题】:Casting double to int using gcc yields weird results使用 gcc 将 double 转换为 int 会产生奇怪的结果
【发布时间】:2017-03-16 03:13:27
【问题描述】:

我有以下程序(koko.c):

#include <stdio.h>
int main(){
    double p = 0.1;
    printf("%lf, %d\n", 1/p, 1/p);
    return 0;
}

如果我尝试使用 gcc koko.c -o koko 编译它,我会收到错误:

koko.c:4:2:警告:格式“%d”需要“int”类型的参数,但参数 3 的类型为“double”[-Wformat=] printf("%lf, %d\n", 1/p, (int) 1/p);

如果我尝试禁用 Wformat(即gcc koko.c -Wformat=0 -o koko),它会编译,但是当我运行它时,我会得到意外的输出: 10.000000, -915298312.

对为什么会发生这种情况有任何想法吗?

【问题讨论】:

  • 错误信息与程序不匹配。请发布您实际使用的程序-您问题中的程序没有任何演员表:-)
  • @psmears - 见上面的打印屏幕。 (我最初有一个演员,但没有它问题仍然存在)。
  • 复制代码并输出文本并粘贴到此处,而不是图像中

标签: c gcc type-conversion


【解决方案1】:

转换运算符有more precedence 比除法。你在做((int)1)/p

【讨论】:

  • 优先级更高,所以它先发生,不是吗?
  • 我使用了令人困惑的术语(较低的优先级数字意味着它首先发生)。这个想法是它首先发生,是的。
  • 当我没有明确写(int)(见上面的打印屏幕)问题仍然存在,你认为是因为同样的原因吗?
  • @RB,printf 参数没有经过类型检查或强制,您有责任确保参数类型与第一个字符串匹配。当你不写 (int) 时,结果以双精度形式传入,但 printf 需要一个整数,这会导致未定义的行为。
【解决方案2】:

运算符优先级。

Cast 是一个比除法优先级更高的运算符,这意味着它首先发生。所以这个:

(int) 1/p

相当于这个:

((int) 1) / p

导致double

你想要这个:

 (int)(1/p)

并启用这些警告! 99.9999% 的时间,编译器都比你聪明!

【讨论】:

  • ...另外,我们应该警告 OP,即使在他解决了这个问题之后,如果 (int)(1/0.1) 不等于 10,他也不应该感到惊讶。
猜你喜欢
  • 2015-11-19
  • 1970-01-01
  • 2019-10-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-03
  • 2017-07-07
  • 1970-01-01
相关资源
最近更新 更多