Reputation: 23200
I am trying to learn basic C programming by following a textbook and I must be missing something about either the data types, rounding, and/or order of operations because when I try to construct a simple program to convert seconds to hours and minutes, the hours work but the remaining minutes come out to 0 when they should not be.
Thanks to Coursera, I am aware that there are huge security vulnerabilities with programs like this, but for learning purposes I'll ask you to ignore security. For now, the books wants me to stick to using printf
, scanf
, and a while
loop as they correspond to the chapters of the textbook I'm reading (the books lets me know that I'll get to start worrying about security when I'm a few chapters further along).
My C program looks like this:
/* 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;
}
I would expect that I could enter 3601
and the result would be:
1 hours and 0.01667 minutes
because this is how the expression is evaluated in the R language, with which I'm more familiar:
> min = 3601/60
> min
[1] 60.02
> hr = min/60
> hr
[1] 1
> min = (3601/60) - (1 * 60)
> min
[1] 0.01667
However, what I get in C is this:
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>
I threw in the 7205
second attempt just for good measure.
I have a feeling that some of the you C gurus on Stack Overflow could use more advanced techniques to write a secure version of the program in some more succinct form. This may be educational as well if you want to mention it, but first and foremost I need to understand what's going on with this simple program.
Upvotes: 3
Views: 164
Reputation: 4023
Integer division: the integer value after dividing two ints gets stored in a floating point format. Eg:
float a = 3/5;
here an integer division will occur between 3
and 5
resulting in 0
. Now, if you try to store this 0
in a float
variable, it will be stored as 0.00
.
min = sec/secpermin;
Should be
min = (float)sec/secpermin;
or
min = sec/(float)secpermin;
or, as @alk pointed out, you could also do this instead:
min = sec;
min /= secpermin; // min=min/secpermin; here, typecasting is not required as
// numerator (min) is already float.
Alternatively, you can make them all float
, and while printing typecast them as int
.
Upvotes: 5