单片机开发进阶技巧:(二)如何判断一个浮点型运算结果是否为整数
上一篇下一篇单变量承担多个标志位及计数功能生产者-消费者模型如何判断一个浮点型运算结果是否为整数这里的整数是数学意义上的整数值如 3.0、-5.0。1方法这个可以间接使用标准库函数floor或ceil实现#includemath.hintis_integer(doublex){// 处理 NaN 和无穷大if(!isfinite(x)){return0;// NaN 或 ±inf 不是整数}returnfloor(x)x;// 或 ceil(x) x}原理对于整数值如4.0floor(4.0) 4.0成立。对于非整数如4.1floor(4.1) 4.0 ! 4.1不成立。2注意事项浮点精度问题由于浮点数的二进制表示存在限制在计算机中某些看似整数的计算结果可能带有微小误差doublex0.10.2;// 实际 ≈ 0.30000000000000004如果是从表达式计算得到的值直接比较floor(x) x可能失败。解决方案允许一个小的容差epsilonintis_integer_eps(doublex,doubleeps){if(!isfinite(x))return0;doublediffx-floor(x);return(diffeps)||(1.0-diffeps);//返回1表示是整数}// 使用示例if(is_integer_eps(result,1e-9)){...}但注意如果函数返回的是精确的整数值如sqrt(9.0)返回3.0则无需 epsilon直接用floor(x) x更安全。整数范围溢出double可精确表示的整数范围约为± 2 53 ±2^{53}±253约 ±9e15。超出此范围的整数无法被double精确表示此时“是否为整数”的判断可能失效。3完整示例#includestdio.h#includemath.hintis_integer(doublex){if(!isfinite(x))return0;returnfloor(x)x;}intmain(void){doubleasqrt(16.0);// 4.0doubleb3.14159;doublec-5.0;printf(%g is integer: %s\n,a,is_integer(a)?yes:no);printf(%g is integer: %s\n,b,is_integer(b)?yes:no);printf(%g is integer: %s\n,c,is_integer(c)?yes:no);return0;}输出4 is integer: yes 3.14159 is integer: no -5 is integer: yes