简体   繁体   中英

Converting minutes into days, hours, minutes and seconds

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;
}

See it live

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM