【问题标题】:Expected value not obtained: why? [duplicate]未获得期望值:为什么? [复制]
【发布时间】:2018-02-06 01:39:41
【问题描述】:

我写了这个非常简单和简短的代码,但它不起作用:当我编译并执行函数 calculateCharges() 的返回值时,我期望 2 时为 0。

谁能解释一下为什么?

#include <stdio.h>
#include <stdlib.h>

float calculateCharges(float timeIn);

int main()
{
    printf("%d", calculateCharges(3.0));
    return 0;
}

float calculateCharges(float timeIn)
{
    float Total;

    if(timeIn <= 3.0)
        Total = 2.0;

    return Total;
}

【问题讨论】:

  • %d 用于int 值。你应该使用%f。 (并且还初始化Total,因为timeIn &lt;= 3.0不是这种情况。)启用编译器警告并注意它们。
  • 您使用不正确的格式说明符调用未定义行为进行转换。 C11 §7.21.6.1(p2 & p9) The fprintf function - insufficient arguments, or incorrect type.
  • 三个问题:第一,Total没有初始化,所以它有一个随机值。其次,您尝试使用 %d 打印浮点数。最后,您可能期望 3.0

标签: c


【解决方案1】:

这里至少存在三个问题,如果您启用编译器警告(-Wall 命令行选项),其中两个应该很容易注意到,并且会导致未定义的行为。

printf 语句中的格式说明符错误。您正在打印一个浮点值 wirh %d,这是有符号整数的格式说明符。正确的说明符是%f。

另一个是使用未初始化的值。如果您的函数中的 if 语句未通过,并且此类用法的行为未定义,则变量 Total可能未初始化。

在我看来,可能是错误的格式说明符导致了错误的输出。但也建议您解决上述第二个问题。

第三个问题与浮点精度有关。在 float 和 double 之间转换值可能不是是安全的往返操作。

您的 3.0 双精度常量在传递给 calculateCharges() 时被强制转换为浮点数。然后在 timeIn &lt;= 3.0 比较中将该值转换为双精度值(以匹配 3.0 的类型)。

3.0 这样的值可能没问题,但在一般情况下它并不安全。例如,请参阅显示问题的这段代码。

#include <stdio.h>

#define EPI 2.71828182846314159265359

void checkDouble(double x) {
    printf("double %s\n", (x == EPI) ? "okay" : "bad");
}

void checkFloat(float x) {
    printf("float %s\n", (x == EPI) ? "okay" : "bad");
}

int main(void) {
    checkFloat(EPI);
    checkDouble(EPI);
    return 0;
}

您可以从输出中看到,将其视为double 总是可以的,但当您转换为float 并失去精度时,情况并非如此:

float bad
double okay

当然,如果您确保始终使用并检查 正确 常量类型(例如使用 3.0F),问题就会消失。

【讨论】:

  • @paxdiablo 感谢您的补充,但在这种情况下,您确实应该发布单独的答案。此外,3.0 可以根据 IEEE 754 精确表示(s=positive, e=1, f=.100000...)
  • iBug,众所周知,答案是社区财产 (stackoverflow.com/help/editing),我认为没有理由复制您已经存在的(和优秀的)答案只是为了增加一个问题。你应该坐下来享受(希望)额外的代表:-)关于3.0的安全问题,你是对的,但我在补充中已经说明了这一点。
  • @paxdiablo 无论如何谢谢。你让我觉得 500k 人都很棒 :)
【解决方案2】:

%d 将打印整数。

Total 是float,所以它不起作用。

您必须为float 使用正确的说明符。

(你应该自己研究,而不是让我们给你答案)

【讨论】:

  • 我知道我应该自己研究它,abelenky,但我知道格式说明符。我只是没有注意到我正在使用 %d。我现在才意识到我是。
猜你喜欢
  • 2013-11-16
  • 2019-07-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多