我正在为C ++课做一些功课,而且我对C ++很陌生。我的if语句遇到了一些问题......我正在做的是,我有一个用户输入时间,介于0.00和23.59之间。 :用一段时间btw代替。那部分有效。然后我分开一小时一分钟,并检查它们以确保它们处于有效的约束状态。检查小时是否有效,但不是分钟...继承我的代码:
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则会再次出错...同时,upvotes会很好:D
答案 0 :(得分:1)
浮点算术(float
和double
)本质上是模糊的。小数点后面总有一些数字,你没有在发送到你的流的圆形表示中看到,并且比较也可能是模糊的,因为你习惯的表示(十进制)不是计算机使用的表示(二进制)。
将时间表示为int hours
和int minutes
,您的问题将逐渐消失。大多数库以刻度(通常是秒或微秒)来测量时间,并且不提供子刻度分辨率。你很好地模仿它们。
答案 1 :(得分:1)
浮点数的比较很容易失败,因为它们中很少有可以在基数2中准确表示。总会有两种不同数字在不同方向上进行舍入的可能性。
最简单的解决方法是为您要比较的数字添加一个非常微小的软糖因子:
if (minute > 0.59 + epsilon)
请参阅What Every Computer Scientist Should Know About Floating-Point Arithmetic。
答案 2 :(得分:0)
不要使用double(也不是float)来存储两个整数值,使用整数和小数部分作为分隔符。十进制数据类型不够精确,因此您可能有错误的结果(如果是圆形)。
在您的情况下,一个好的解决方案是使用结构(或一对)甚至整数。
使用整数,您可以使用当时的倍数的mod或div来提取实际值。例如:
int startTime = 2359;
int hour = startTime / 100;
int minute = startTime % 100;
虽然使用struct,代码看起来更简单,更容易理解(和维护)。
答案 3 :(得分: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;
处理积分值时,使用起来要简单得多 积分类型。