-1

我正在为 C++ 课程做一些功课,而且我对 C++ 还是很陌生。我的 if 语句遇到了一些问题……我在做什么,是让用户输入一个时间,介于 0.00 和 23.59 之间。: 被替换为句号。那部分有效。然后我将小时和分钟分开,并检查它们以确保它们处于有效的约束中。检查小时有效,但不是一分钟......这是我的代码:

minute= startTime - static_cast<int>(startTime);
hour= static_cast<int>(startTime);

//check validity
if (minute > 0.59) {
    cout << "ERROR! ENTERED INVALID TIME! SHUTTING DOWN..." << endl;;
    return(0);
}
if (hour > 23) {
    cout << "ERROR! ENTERED INVALID TIME! SHUTTING DOWN..." << endl;;
    return(0);
}

同样,如果我输入 23,小时有效,但如果我输入 23.59,我会收到错误,但如果我输入 23.01,我不会。另外,如果我输入 0.59 它也会给出错误,但不是 0.58。我尝试切换if(minute > 0.59)if(minute > 0.6)但由于某种原因导致其他地方出现问题。我完全不知道该怎么做,所以任何帮助都会很棒!太感谢了!

编辑:我刚输入 0.58,它没有给我错误...但是如果我将其设为 1.59,它会再次出现错误...此外,赞成票会很好:D

4

4 回答 4

1

浮点运算 (floatdouble) 本质上是模糊的。小数点后面总有一些数字是您在发送到流的舍入表示中看不到的,并且比较也可能是模糊的,因为您习惯的表示(十进制)不是计算机使用的表示(二进制)。

将时间表示为int hoursint minutes,您的问题就会消失。大多数库以刻度(通常是秒或微秒)为单位测量时间,并且不提供子刻度分辨率。你很好地模仿他们。

于 2013-02-20T15:36:38.263 回答
1

浮点数的比较很容易失败,因为它们中很少有人可以精确地以 2 为基数表示。两个不同的数字总是有可能在不同的方向上四舍五入。

最简单的解决方法是在您要比较的数字上添加一个非常小的软糖因子:

if (minute > 0.59 + epsilon)

看看每个计算机科学家应该知道的关于浮点运算的知识

于 2013-02-20T15:37:17.823 回答
0

永远不要使用 double(或 float)来存储两个整数值,并使用整数和小数部分作为分隔符。十进制数据类型不够精确,因此您可能会得到错误的结果(如果是一轮)。

在您的情况下,一个好的解决方案是使用一个结构(或一对)甚至一个整数。

使用整数,您可以使用 mod 或 div 的倍数来提取实际值。例子:

int startTime = 2359;
int hour = startTime / 100;
int minute = startTime % 100;

虽然,使用 struct 代码看起来更简单,更容易理解(和维护)。

于 2013-02-20T15:43:03.603 回答
0

你无法准确地比较0.59;该值无法在机器中表示。您正在将非常接近的东西与非常接近0.59的东西进行比较0.59

就个人而言,我根本不会以这种方式输入时间。一个更好的解决方案是学习如何使用std::istream来读取值。但是如果你坚持,并且你有startTime你的double,你需要将它乘以100.0(这样你感兴趣的所有值都是整数,并且可以精确表示),然后将它四舍五入,然后将其转换为整数,然后使用整数上的模和除法运算符来提取您的值。类似于以下内容:

assert( startTime >= 0.0 && startTime <= 24.0 );
int tmpTime = 100.0 * startTime + 0.5;
int minute = tmpTime % 100;
int hour = tmpTime / 100;

在处理整数值时,使用整数类型要简单得多。

于 2013-02-20T15:45:38.047 回答