我正在编写一个代码,我需要检查一个可以采用double值的变量是否实际上采用了一个整数值。我认为双变量如果在整数的容差范围内,则采用整数值。这个公差是1e-5。
以下是我的代码:
#define SMALL 1e-5
//Double that attains this is considered non zero. Strictly Less than this is 0
int check_if_integer(double arg){
//returns 1 if arg is close enough to an integer
//returns 0 otherwise
if(arg - (int)arg >= SMALL){
if(arg + SMALL > (int)(arg+1.0)){
return(1);
//Code should have reached this point since
//arg + SMALL is 16.00001
//while (int)(arg+1.0) should be 16
//But the code seems to evaluate (int)(arg+1.0) to be 17
}
}
else{
return(1);
}
return(0);
}
int main(void){
int a = check_if_integer(15.999999999999998);
}
不幸的是,在传递参数15.999999999999998时,函数返回0.也就是说,它认为参数是小数,而它应该返回1表示参数是"足够接近"到16岁。
我正在使用VS2010专业版。
任何指针都将非常感谢!
答案 0 :(得分:2)
是的,浮点很难。仅仅因为15.999999999999998 < 16.0
,这并不意味着15.999999999999998 + 1.0 < 17.0
。假设您有一个三位精度的十进制浮点类型。对于9.99 + 1.0
,该类型的精度会得到什么结果?数学结果为10.99
,并四舍五入到该类型的精度给出11.0
。二进制浮点具有相同的问题。
在这种特殊情况下,您可以将(int)(arg+1.0)
更改为(int)arg+1
。 (int)arg
是准确的,整数加法也是如此。
答案 1 :(得分:2)
继hvd对类型的回答;由于它们在内部表示的方式,因此不建议在大型双打中加/减小双打。
一个简单的工作可以避免这两个问题:
if (abs(arg - round(arg)) <= SMALL) {
return (1);
} else {
return (0);
}