【问题标题】:Converting minutes into days, hours, minutes and seconds将分钟转换为天、小时、分钟和秒
【发布时间】:2020-09-03 18:32:44
【问题描述】:

我正在上初学者级别的 C++ 课程,但是当我在 C++ 中将分钟转换为天、小时、分钟和秒时,我无法弄清楚为什么会得到错误的输出。

我有一个朋友帮助我,她能够使用相同的数学在 Python 中获得正确的输出,但由于某种原因,在 C++ 中我无法在几秒钟内获得正确的输出。我确信有一个更简单的方法来获取输出,但这是教授希望我们编写它的方式。

例如,输入为 10.5,代码输出 0d 0h 10m 0s 而不是 0d 0h 10m 30s。

代码如下:

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

我觉得这与将 int 转换为 double 有关,但如果不是这种情况,那么我不确定它可能有什么问题。任何帮助表示赞赏,谢谢。

【问题讨论】:

  • 这里是你放松的地方:inputMinutes = decimalMinutes;.
  • 你不能cin &gt;&gt; decimalMinutes吗?
  • 你很幸运,0.5 可以精确地表示为 double。如果您要尝试另一个值,例如 10.33,如果舍入问题导致错误答案,请不要感到惊讶。
  • 我有一个朋友帮助我,她能够在 Python 中得到正确的输出——Python 不是 C++。无论你的朋友做什么,它都可能不适用于 C++ 程序。
  • 当我删除 inputMinutes = decimalMinutes;它根本不输出任何值。

标签: c++


【解决方案1】:

正如其他用户已经指出的那样,当您编写 inputMinutes = decimalMinutes; 时,您会将 double 转换为 int,从而丢失有关小数部分的所有信息。您必须将此部分与 decimalMinutes 变量的整数部分分开,然后将其乘以 60 以获得秒数。请参阅下面的代码。

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

这应该可行:这些是我的一些输出。

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

您会看到仍然存在一些舍入问题(如果您想计算 1/3 分钟,您应该输入周期数 0.333333333...,并且 0.1 的表示形式在浮点算术中是周期性的),这是由于如何处理从double 到int 的转换(请参阅@PaulMcKenzie 对您的回答的评论)。

【讨论】:

  • 一分钟的 1/3 是 20 秒。 1/3 不等于 0.3
  • @Mestkon 你是对的,我认为不准确。我会举一些更有意义的例子来阐明我的观点。
【解决方案2】:

使用整数是个问题。将 inputMinutes 更改为双精度并使用 fmod。这段代码应该可以工作。

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

【讨论】:

  • 我认为没有必要给fmod() 打这么多电话。只需将输入乘以 60,转换为 int 或 long,然后使用整数秒,就更简单了。
  • 我不确定 fmod 是什么,但他确实明确表示,即使我们知道 C++,他也希望实验室只使用我们已经研究过的材料。
  • @Slava 所以我基本上应该将分钟转换为秒,然后再将秒转换为其他所有内容?
  • @efan Fmod 只是取模,但返回一个浮点数。但是,如果您只能使用所学的知识,那就足够了。 Slava 的想法应该可行。
【解决方案3】:

您可以使用std::chrono 命名空间中的定义,而不是自己保存数字之间的比率。

#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

【讨论】:

    【解决方案4】:

    由于您不关心几分之一秒,您可以简单地将输入乘以 60,然后全部取整:

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

    请注意,从 double 转换为 integer 本质上是向下舍入。例如,(int) 0.9 为零。如果你想四舍五入到最接近的数字,我们就必须变得更复杂。

    除此之外,我强烈建议您阅读有关使用调试器的教程。如果您使用了一个,您会发现您的变量丢失了一些数据。
    或者或另外,了解如何使用控制台消息 (std::cout) 进行调试。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-01-06
      • 2012-09-27
      • 1970-01-01
      • 2015-05-18
      • 2017-05-10
      相关资源
      最近更新 更多