为什么在C中执行算术后会丢失剩余的值?

Hac*_*k-R 3 c

我试图通过遵循教科书来学习基本的C编程,我必须遗漏一些关于数据类型,舍入和/或操作顺序的东西,因为当我尝试构建一个简单的程序来将秒转换为小时和分钟时,小时工作,但剩余的分钟在不应该的时候达到0.

感谢Coursera,我知道像这样的程序存在巨大的安全漏洞,但出于学习目的,我会要求你忽略安全性.现在,书籍要我坚持使用printf,scanfwhile循环,因为它们对应于我正在阅读的教科书的章节(书籍让我知道,当我是一个教科书时,我会开始担心安全问题几个章节继续).

我的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;
}
Run Code Online (Sandbox Code Playgroud)

我希望我可以进入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
Run Code Online (Sandbox Code Playgroud)

但是,我在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>
Run Code Online (Sandbox Code Playgroud)

7205为了好的措施,我投入了第二次尝试.

我有一种感觉,Stack Overflow上的一些C大师可以使用更先进的技术以更简洁的形式编写程序的安全版本.如果你想提及它,这也可能具有教育意义,但首先我需要了解这个简单程序正在发生什么.

Ayu*_*Jha 5

整数除法:除以两个整数后的整数值以浮点格式存储.例如:

 float a = 3/5;
Run Code Online (Sandbox Code Playgroud)

这里将产生整数除法35产生0.现在,如果您尝试将其存储0float变量中,它将存储为0.00.

    min = sec/secpermin;
Run Code Online (Sandbox Code Playgroud)

应该

    min = (float)sec/secpermin;
Run Code Online (Sandbox Code Playgroud)

要么

    min = sec/(float)secpermin;
Run Code Online (Sandbox Code Playgroud)

或者,正如@alk指出的那样,你也可以这样做:

    min = sec;     
    min /= secpermin;    // min=min/secpermin;   here, typecasting is not required as 
                        // numerator (min) is already float.
Run Code Online (Sandbox Code Playgroud)

或者,您可以将它们全部制作出来float,同时将它们打印成类型int.

  • 更清楚的解释:整数除法的结果是"C"中的整数,小数部分被丢弃.其中一个整数的浮动转换为浮动分区,按预期工作 (3认同)
  • 尽管OP打算进行浮点划分,但至少应该警告他这种方法存在严重的舍入误差 - 并告诉余数运算符.您可以...吗? (2认同)