3

在用 C 编写程序以将摄氏度转换为华氏度时,以下公式给出了不正确的输出:

    int fahr = 9 / 5 * celsius + 32;

现在,我知道这可能是 9/5 被解释为整数的问题,但我不明白的是,使用doublefloat它仍然给出相同的错误输出。

奇怪的是,尽管也将类型设置为,但以下公式给出了正确的输出int

int fahr = celsius / 5 * 9 + 32;

此外,我注意到即使像下面这样简单的东西,当类型设置为 时double,输出仍然是 1.0 而不是 1.8:

 double x = 9 / 5;
 printf("%lf\n", x);

我读过这个线程:

C程序将华氏温度转换为摄氏温度

但我仍然不明白为什么int fahr = celsius / 5 * 9 + 32;有效但无效int fahr = 9/5 * celsius+32;

4

3 回答 3

8

你正在用整数做数学。这个表达式:

9 / 5

C 中的产量1。当您说您使用doubleorfloat时,您可能只是更改了 的类型fahr,这对发生在 assignemtn 运算符右侧的操作没有任何作用。要获得正确的行为,您还需要将这些常量中的至少一个设为 a double

9.0 / 5

同样,在此声明中:

double x = 9 / 5;

您仍在进行整数数学运算,然后将结果分配给double变量。没有其他事情发生。通过执行以下操作之一,您将得到正确的答案:

double x = 9.0 / 5;
double x = 9 / 5.0;
double x = 9.0 / 5.0;

这个表达式的原因:

int fahr = celsius / 5 * 9 + 32;

似乎工作只是一个操作顺序的事情 - 在这里你将输入除以 5,然后乘以 9,而不是先进行常量操作。通过执行以下操作,您仍然可以获得更准确的答案:

int fahr = celsius * 9 / 5 + 32;

除此之外,您还可以在此表达式中进行浮点数学运算:

int fahr = celsius * 9.0 / 5 + 32;

如果你想使用整数进行原始计算,你当然可以 - 你只需要在除法之前相乘:

int fahr = 9 * celsius / 5 + 32;

此表达式等效于上面使用的表达式之一。

于 2013-04-18T00:33:16.913 回答
1

(在大多数情况下)评估每个表达式或子表达式的类型,而不考虑它出现的上下文。

在此声明中:

double x = 9 / 5;

初始化表达式是9 / 5;它由两个int表达式和一个除法运算符组成。由于 的操作数/是类型int的,所以它是一个int除法,产生一个int值。由于整数除法会截断,结果是1, 类型int

然后使用该表达式的结果来初始化x. 由于xis 的类型double,该值被隐式地从intto转换double,从而导致x持有该值1.0

如果你想要的值x1.8,你需要做浮点除法,这意味着你需要浮点操作数。最简单和最清晰的方法是:

double x = 9.0 / 5.0;

还有其他几种(恕我直言不太清楚)方法。如果一个/运算符有两个操作数,一个是 type int,一个是 type double,则int操作数被提升为double,因此其中任何一个也将设置x1.8

double x = 9.0 / 5;
/* or */
double x = 9 / 5.0;

但要小心这种方法:

double y = 9 / 5 / 3.0;

这相当于:

double y = (9 / 5) / 3.0;

它计算9 / 5int, yielding 1,然后将该结果提升为 ,double并除以3.0, yielding 0.333333333

关键是表达式的上下文不会对表达式或其操作数强加类型;表达式被评估为好像它是孤立的,然后可以根据其上下文转换结果。

于 2013-04-18T00:37:08.357 回答
1

我仍然不明白为什么int fahr = celsius / 5 * 9 + 32;有效但无效int fahr = 9/5 * celsius+32;

对于前者,您可能将其声明celsius为 afloat或 a double,从而使整个右侧如此评估。假设您使用float,它的工作原理如下:

celsius / 5 * 9 + 32
(celsius / 5.0) * 9 + 32
(celsius / 5.0 * 9.0) + 32
(celsius / 5.0 * 9.0 + 32.0)

对于后者,9/5是整数算术,1在其余数学作为浮点数发生之前计算。在这种情况下:

9 / 5 * celsius + 32
1 * celsius + 32 // Because of this, you get an incorrect answer
celsius + 32
celsius + 32.0

注意左侧的类型无关紧要;右侧的评估不考虑这一点。

更新:您说celsius的是int,这意味着您碰巧幸运并使用 的倍数进行测试,在对语句的其余部分执行有效的整数运算之前5为您提供正确的整数结果。celsius / 5在你的第二个例子中,作为一个倍数对5你没有帮助。

无论如何,现在您知道自己为什么幸运了,但是链接的问题为您提供了实际需要做的事情的celsius答案5那里的答案。

于 2013-04-18T00:37:34.500 回答