C 为什么除法的结果是零而不是小数?

C 为什么除法的结果是零而不是小数?,c,C,教我自己C,发现当我做一个温度转换方程时,除非我把分数改成小数,否则它是不起作用的。即 tempC=(.555*(tempF-32))将起作用,但tempC=((5/9)*(tempF-32))将不起作用 为什么? 根据《C Primer Plus》一书,它应该可以工作,因为我对tempC和tempF都使用浮点数。在第二种情况下,似乎有整数除法: tempC=((5/9)*(tempF-32)) 5/9将被截断为零 要解决此问题,需要将其中一个设置为浮点类型: tempC=((5./9.)*(

教我自己C,发现当我做一个温度转换方程时,除非我把分数改成小数,否则它是不起作用的。即

tempC=(.555*(tempF-32))
将起作用,但
tempC=((5/9)*(tempF-32))
将不起作用

为什么?

根据《C Primer Plus》一书,它应该可以工作,因为我对tempC和tempF都使用浮点数。

在第二种情况下,似乎有整数除法:

tempC=((5/9)*(tempF-32))
5/9
将被截断为零

要解决此问题,需要将其中一个设置为浮点类型:

tempC=((5./9.)*(tempF-32))

如果将5/9放在括号中,将首先计算,因为这是两个整数,所以将通过整数除法进行计算,结果将为0,然后再计算表达式的其余部分

可以重新排列表达式,以便首先转换为浮点:

tempC=((5/9)*(tempF-32))→  <代码>tempC=(5*(tempF-32))/9


当然,正如其他人所说,使用浮点常量。

5/9
是一个整数表达式,因此它被截断为0。编译器应该警告您这一点,否则您应该考虑启用警告。

当您执行5/9时,5和9都是整数,并且会发生整数除法。整数除法的结果是一个整数,它是两个操作数的商。所以,在5/9的情况下,商是0,因为你乘以0,tempC就是0。为了不进行整数除法,两个操作数中至少有一个必须是
float


例如,如果使用5.0/9或5/9.0或5.0/9.0,它将按预期工作。

5/9是整数除法,而不是浮点除法。这就是为什么你会得到错误的结果

使用5或9浮点变量,您将得到正确答案


就像5.0/9或5/9.0一样,它是截断,而不是四舍五入。谢谢你的术语修复。:)啊!谢谢现在这是有道理的。我看到一些例子中有小数点,但硬币没有掉下来。谢谢大家!为了谨慎起见,5.0/9.0语法提供了两个双精度。如果tempF和tempC是
float
,则表达式应为5.0f/9.0f。否则,可能会对双精度执行除法,然后在存储结果时将其四舍五入为浮点精度。希望编译器足够聪明,可以优化这个小问题,但我不会指望它。@Lundin它不能优化它;如果使用双精度,必须这样做,否则可能会出现意外的答案。即使它们不在括号中,也可以作为整数计算。此表达式的求值顺序在C中是未指定的行为,编译器可能选择从左到右或从右到左求值,并且您无法知道适用的求值顺序。不完全正确。括号确实有效果!如果确保执行的第一次计算结果为浮点,则表达式的其余部分将不会恢复为整数。我补充了我的答案来说明我的意思。重写的示例并不等同于删除括号,您故意更改了计算顺序<代码>tempC=5/9*(tempF-32)是一个删除括号的示例。这个例子可能给出也可能不给出所需的结果,这取决于编译器是从左到右还是从右到左求值——它依赖于未指定的行为。我不确定您在这里试图证明什么。我的示例重写了OP的表达式,使其能够工作。这正是他们要求的。我真的不明白为什么它应该发出警告。编译器无法判断有人希望他们的整型常量是什么值。@Lundin:这就是为什么它会是一个(迂腐的)警告。如果一个常量整数表达式的结果为零,那么它应该是零,或者有疏忽。不一定,在很多情况下,您可能需要一个结果为0的常量表达式。例如
result=SOME_常量&MASK很可能导致零。假设您在整个代码中都有类似的位屏蔽操作,使用不同的屏蔽。那么你不会想要成百上千的警告,为什么仅仅因为你编写了通用的、一致的代码而没有任何神奇的数字就要受到惩罚呢?@Lundin:但这不是除法,我这里只指除法。
一些常量/一些东西
与我的示例没有什么不同。假设常数表示该程序构建使用的输出数量,除法用于计算输出的性质。同意。将表示浮点的
f
添加到常量中始终是一种良好的做法。同样,无符号整数常量的
u