
在java等编程语言中,float和double类型的浮点数采用二进制浮点表示法存储。这意味着许多在十进制中看似简单的数字(例如0.1、0.2、1.20、2.00)在转换为二进制时,可能无法被精确表示,而只能得到一个非常接近的近似值。这种近似值在进行数学运算时,会导致微小的误差累积。
考虑以下一个常见的场景,一个while循环旨在从1.20递增到2.00,每次增加0.02:
float weight = 60 ;
float height01 = 1.20 ;
float height02 = 2.00 ;
while( height01 < height02 ) {
float BMI = ( weight / (height01 * height01) ) ;
System.out.println( height01 + " , " + BMI ) ;
height01 = height01 + 0.02 ;
}期望的输出是height01最终达到2.00并打印相应的值,但实际输出可能在1.9999993处停止,并未达到2.00。这是因为:
为了解决浮点数在循环条件判断中的精度问题,我们可以采用以下两种常用方法:
这种方法的核心思想是避免直接使用浮点数作为循环的终止条件,而是通过计算总的迭代次数,然后使用一个整数计数器来控制循环。在每次迭代中,再根据计数器的值来计算当前的浮点数值。
立即学习“Java免费学习笔记(深入)”;
float weight = 60.0f;
float height01 = 1.20f;
float height02 = 2.00f;
float delta = 0.02f;
// 计算总的步数,使用lround进行四舍五入以处理潜在的浮点数除法误差
long n = Math.round((height02 - height01) / delta);
// 使用整数i控制循环,从0到n(包含n)
for (long i = 0; i <= n; i++) {
// 根据i和delta计算当前height值,确保精确性
float currentHeight = height01 + i * delta;
float BMI = (weight / (currentHeight * currentHeight));
System.out.println(currentHeight + " , " + BMI);
}注意事项:
这种方法通过在循环的终止条件中引入一个小的容差(epsilon)来解决问题。由于浮点数可能永远不会精确地等于目标值,我们可以将循环条件放宽为“小于或等于目标值加上一个小的容差”。
float weight = 60.0f;
float height01 = 1.20f;
float height02 = 2.00f;
float delta = 0.02f;
// 定义一个容差值,通常是步长的一半
float height02plus = height02 + delta / 2;
// 循环条件改为小于等于目标值加上容差
while (height01 <= height02plus) {
float BMI = (weight / (height01 * height01));
System.out.println(height01 + " , " + BMI);
height01 = height01 + delta;
}注意事项:
浮点数精度问题是编程中常见的陷阱。当涉及到循环控制、精确比较或金融计算时,尤其需要注意。
通过理解浮点数的底层表示和其固有的精度限制,并采用上述策略,开发者可以编写出更健壮、更准确的浮点数处理代码,有效避免循环中的意外行为。
以上就是避免浮点数循环中的精度误差:Java编程实践的详细内容,更多请关注php中文网其它相关文章!
编程怎么学习?编程怎么入门?编程在哪学?编程怎么学才快?不用担心,这里为大家提供了编程速学教程(入门课程),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号