I'm in a beginner level C++ class and I'm having some trouble figuring out why I'm getting the wrong output when I convert minutes into days, hours, minutes and seconds in C++.
I had a friend help me and she was able to get the correct output in Python using the same math, but for some reason in C++ I can't get the correct output for the seconds. I'm sure there's a much much easier way to get the output, but this is how to professor wants us to write it.
For example, the input would be 10.5 and the code outputs 0d 0h 10m 0s instead of 0d 0h 10m 30s.
Here's the code:
#include <iostream>
using namespace std;
int main() {
//get the starting number of minutes
int inputMinutes;
double decimalMinutes;
cout << "Enter number of minutes: ";
cin >> decimalMinutes;
//allow decimal input
inputMinutes = decimalMinutes;
//get number of days
int days = inputMinutes / 1440;
inputMinutes = inputMinutes % 1440;
//get number of hours
int hours = inputMinutes / 60;
//get number of minutes
int mins = inputMinutes % 60;
int seconds = inputMinutes % 1 * 60;
//output days, hours, minutes and seconds
cout << days << "d " << hours << "h " << mins << "m " << seconds << "s" << endl;
}
I have a feeling it's something to do with casting the int to a double but if that's not the case, then I'm not sure what could be wrong with it. Any help is appreciated, thanks.
Its a problem with using an integer. Change inputMinutes to a double and use fmod. This code should work.
#include <iostream>
#include <math.h>
using namespace std;
int main() {
//get the starting number of minutes
double inputMinutes;
double decimalMinutes;
cout << "Enter number of minutes: ";
cin >> decimalMinutes;
//allow decimal input
inputMinutes = decimalMinutes;
//get number of days
int days = inputMinutes / 1440;
inputMinutes = fmod(inputMinutes,1440);
//get number of hours
int hours = inputMinutes / 60;
//get number of minutes
int mins = fmod(inputMinutes,60);
int seconds = fmod(inputMinutes,1) * 60;
//output days, hours, minutes and seconds
cout << days << "d " << hours << "h " << mins << "m " << seconds << "s" << endl;
}
As other users already pointed out, when you write inputMinutes = decimalMinutes;
you convert a double
into a int
, loosing all the information about the decimal part. You have to separate this part from the integer part of your decimalMinutes
variable, then multiply it by 60 to get the seconds. See the below code.
#include <iostream>
int main() {
//get the starting number of minutes
int inputMinutes;
double decimalMinutes;
double decPart;
std::cout << "Enter number of minutes: ";
std::cin >> decimalMinutes;
//allow decimal input
inputMinutes = decimalMinutes;
decPart = decimalMinutes-inputMinutes;
//get number of days
int days = inputMinutes / 1440;
inputMinutes = inputMinutes % 1440;
//get number of hours
int hours = inputMinutes / 60;
//get number of minutes
int mins = inputMinutes % 60;
int seconds = decPart * 60;
//output days, hours, minutes and seconds
std::cout << days << "d " << hours << "h " << mins << "m " << seconds << "s" << std::endl;
return 0;
}
This should work: these are some of my outputs.
Enter number of minutes: 10.5
0d 0h 10m 30s
Enter number of minutes: 126.3333333
0d 2h 6m 19s
Enter number of minutes: 1440.4
1d 0h 0m 24s
Enter number of minutes: 12.1
0d 0h 12m 5s
You see that there are still some rounding issues (if you want to compute 1/3 of a minute you should input the periodic number 0.333333333..., and the representation of 0.1 is periodic in floating point arithmetic) and this is due to how the conversion from double
to int
is handled (see @PaulMcKenzie's comment to your answer).
As an alternative to holding the ratios between numbers yourself, you could use the definitions in the std::chrono
namespace.
#include <iostream>
#include <chrono>
using f_minutes = std::chrono::duration<double, std::chrono::minutes::period>;
int main() {
//get the starting number of minutes
double input;
std::cout << "Enter number of minutes: ";
std::cin >> input;
f_minutes decimalMinutes(input);
auto days = duration_cast<std::chrono::days>(decimalMinutes);
decimalMinutes -= days;
auto hours = duration_cast<std::chrono::hours>(decimalMinutes);
decimalMinutes -= hours;
auto mins = duration_cast<std::chrono::minutes>(decimalMinutes);
decimalMinutes -= mins;
auto seconds = duration_cast<std::chrono::seconds>(decimalMinutes);
//output days, hours, minutes and seconds
std::cout << days.count() << "d " << hours.count() << "h " << mins.count() << "m " << seconds.count() << "s" << std::endl;
}
Since you do not care for fractions of seconds, you could simply go by multiplying your input with 60 and then going all integer:
int main() {
int inputSeconds; // << I changed this to seconds here
double decimalMinutes;
cout << "Enter number of minutes: ";
cin >> decimalMinutes;
inputSeconds = 60.*decimalMinutes; // << times 60, now contains the seconds as a whole number
int days = inputSeconds / (1440*60); // I do a multiplication here to make it clear for you what is happening
...
}
Note that casting from double to integer essentially rounds down. For example, (int) 0.9
is zero. If you want to round to the closest number, we'd have to go more complex.
Other than that, I strongly recommend for you to read a tutorial on using a debugger. If you used one, you would have seen that your variable had lost some data.
Alternatively or additionally, learn how to debug using console messages ( std::cout
).
有人可以帮助我在几小时和几秒内用 C++ 制作一个天数转换器吗?
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.