sid*_*yll 65 c floating-point int
如何检查float
变量是否包含整数值?到目前为止,我一直在使用:
float f = 4.5886;
if (f-(int)f == 0)
printf("yes\n");
else printf("no\n");
Run Code Online (Sandbox Code Playgroud)
但我想知道是否有更好的解决方案,或者这个解决方案是否存在任何(或许多)缺点.
Mar*_*utz 66
除了已经给出的好答案,你也可以使用ceilf(f) == f
或floorf(f) == f
.true
如果f
是整数,则两个表达式都返回.它们也返回false
NaNs(NaNs总是比较不相等)和true
±无穷大,并且没有溢出用于保存截断结果的整数类型的问题,因为floorf()
/ ceilf()
return float
s.
Jas*_*n C 19
请记住,此处的大多数技术都是有效的,假设由于先前计算而导致的舍入误差不是一个因素.你可以使用roundf
,像这样:
float z = 1.0f;
if (roundf(z) == z) {
printf("integer\n");
} else {
printf("fraction\n");
}
Run Code Online (Sandbox Code Playgroud)
这个和其他类似技术(例如ceilf
,转换为long
等)的问题在于,虽然它们对于整数常量很有效,但如果数字是一个受浮点圆计算的结果,它们将会失败 - 错误.例如:
float z = powf(powf(3.0f, 0.05f), 20.0f);
if (roundf(z) == z) {
printf("integer\n");
} else {
printf("fraction\n");
}
Run Code Online (Sandbox Code Playgroud)
打印"分数",即使(3 1/20)20应该等于3,因为实际计算结果最终为2.9999992847442626953125.
任何类似的方法,fmodf
无论是它还是其他方式都受此约束.在执行复杂或易于舍入的计算的应用程序中,通常您要做的是为构成"整数"的内容定义一些"容差"值(这通常用于浮点相等比较).我们经常称这种公差为epsilon.例如,假设我们原谅计算机最多+/- 0.00001舍入误差.然后,如果我们正在测试z
,我们可以选择0.00001的epsil并执行:
if (fabsf(roundf(z) - z) <= 0.00001f) {
printf("integer\n");
} else {
printf("fraction\n");
}
Run Code Online (Sandbox Code Playgroud)
你真的不想在ceilf
这里使用,因为例如ceilf(1.0000001)
2不是1,而ceilf(-1.99999999)
-1不是-2.
如果您愿意,可以使用rintf
它代替roundf
.
选择适合您的应用的公差值(是的,有时零容差是合适的).有关更多信息,请查看有关比较浮点数的文章.
if (fmod(f, 1) == 0.0) {
...
}
Run Code Online (Sandbox Code Playgroud)
别忘了math.h
和libm
.
if (f <= LONG_MIN || f >= LONG_MAX || f == (long)f) /* it's an integer */
Run Code Online (Sandbox Code Playgroud)