话不多说,先上一个简单的示例代码:
#include <iostream>
#include <cstdlib>
#include <cmath>
int main() {
float alpha = 0.04;
int32_t result_a = ceil(1.0 / alpha);
int32_t result_b = ceil(1 / alpha);
std::cout << "result_a:" << result_a << std::endl;
std::cout << "result_b:" << result_b << std::endl;
std::cout.precision(20);
std::cout << "ceil(1.0 / alpha) = " << (1.0 / alpha) << std::endl;
std::cout << "ceil(1 / alpha) = " << (1 / alpha) << std::endl;
return 0;
}
乍一看 r e s u l t _ a result\_a result_a和 r e s u l t _ b result\_b result_b的结果应该没什么区别, a l p h a alpha alpha是一个 f l o a t float float类型变量,分子会隐式地转换成单精度浮点类型。但实际的输出结果却不是和我想的一样:
result_a:26
result_b:25
ceil(1.0 / alpha) = 25.00000055879355898
ceil(1 / alpha) = 25
从结果打印来看,当分子为1.0的时候, 1.0 / a l p h a 1.0/alpha 1.0/alpha的值的小数位存在大于零的情况,故向上取整之后的结果比数学上计算的结果多1。遇到这种以及类似的情形需要特别小心,否则极容易引起代码的精度问题、内存泄漏与越界等问题。避免这种情况的一个有效方法是可以考虑将求倒数和向上取整分为两个计算步骤:
float temp = 1.0 / alpha;
int result = ceil(temp);