提问人:Hack-R 提问时间:5/6/2015 最后编辑:ChrisFHack-R 更新时间:5/6/2015 访问量:140
为什么在 C 中执行算术运算后会丢失值的余数?
Why do I lose the remainder of a value after performing arithmetic in C?
问:
我正在尝试通过遵循教科书来学习基本的 C 编程,我一定缺少一些关于数据类型、舍入和/或运算顺序的东西,因为当我尝试构建一个简单的程序将秒转换为小时和分钟时,小时有效,但剩余的分钟数在不应该出现时变为 0。
多亏了 Coursera,我知道这样的程序存在巨大的安全漏洞,但出于学习目的,我会请您忽略安全性。就目前而言,这些书希望我坚持使用、和循环,因为它们与我正在阅读的教科书的章节相对应(这些书让我知道,当我再读几章时,我会开始担心安全性)。printf
scanf
while
我的 C 程序如下所示:
/* Ask the user for a number of seconds, convert to X hours and Y minutes */
/* Continue doing this with a while loop until user enters 0 */
#include <stdio.h>
#include <conio.h>
#include <string.h>
int main(void)
{
const int minperhour = 60;
const int secpermin = 60;
int sec, hr;
float min;
sec = 1;
while(sec != 0)
{
printf("Enter the number of seconds to convert: \n");
scanf("%i", &sec);
min = sec/secpermin;
hr = min/minperhour;
min = (sec/secpermin) - (hr * minperhour);
printf("%d hours and %f minutes \n", hr, min);
}
return 0;
}
我希望我可以进入,结果将是:3601
1 hours and 0.01667 minutes
因为这是我更熟悉的 R 语言中表达式的计算方式:
> min = 3601/60
> min
[1] 60.02
> hr = min/60
> hr
[1] 1
> min = (3601/60) - (1 * 60)
> min
[1] 0.01667
但是,我在 C 中得到的是这样的:
C:\Users\hackr>pa2q3.exe
Enter the number of seconds to convert:
3601
1 hours and 0.000000 minutes
Enter the number of seconds to convert:
7205
2 hours and 0.000000 minutes
Enter the number of seconds to convert:
0
0 hours and 0.000000 minutes
C:\Users\hackr>
我第二次尝试只是为了好好衡量。7205
我有一种感觉,Stack Overflow 上的一些 C 专家可以使用更高级的技术以更简洁的形式编写程序的安全版本。如果你想提到它,这可能也很有教育意义,但首先我需要了解这个简单的程序是怎么回事。
答:
5赞
Ayushi Jha
5/6/2015
#1
整数除法:除以两个整数后的整数值以浮点格式存储。例如:
float a = 3/5;
这里,和之间将发生整数除法,结果为 。现在,如果您尝试将其存储在变量中,它将存储为 .3
5
0
0
float
0.00
min = sec/secpermin;
应该是
min = (float)sec/secpermin;
或
min = sec/(float)secpermin;
或者,正如@alk指出的那样,您也可以这样做:
min = sec;
min /= secpermin; // min=min/secpermin; here, typecasting is not required as
// numerator (min) is already float.
或者,您可以将它们全部设置为 ,并在打印时将它们类型化为 .float
int
评论
0赞
Hack-R
5/6/2015
谢谢。我想知道我是否在书中错过了这一点,或者这是否是新信息。我将不得不仔细检查。无论哪种方式,这都非常有帮助,我会接受它作为解决方案,谢谢!
3赞
DrKoch
5/6/2015
更清晰的解释:整数除法的结果是小数部分中的整数被丢弃。将其中一个整数转换为浮点数将其转换为按预期工作的浮点除法C
2赞
jsbueno
5/6/2015
尽管 O.P. 打算进行浮点除法,但您至少应该警告他,这种方法存在严重的舍入误差 - 并告知余数运算符。你能吗?
1赞
alk
5/6/2015
或不带铸件:min = sec; min /= secpermin;
1赞
alk
5/6/2015
此外,在分配时也不需要强制转换,因为已经键入了。Short:不是整数除法。hr
min
float
min/minperhour;
评论