使用Math.Round设置三角形周长精度未达预期,求解决方法
问题分析与解决方案
核心问题根源
Math.Round仅负责对数值进行四舍五入到指定小数位,但double类型无法存储末尾的零——比如6.000和6.0在double中是完全相同的数值,因此返回double的话,无论怎么处理都无法得到带末尾零的格式,这些零属于格式化展示的范畴,不是数值本身的属性。
另外你的代码还有两个语法/逻辑错误:
- Java不支持方法参数默认值(
int precision = 2是C#语法),需要通过方法重载实现默认精度。 - 三角形有效性判断错误:应该判断
a + b <= c(两边之和等于第三边是退化三角形,不属于有效三角形),原代码的<会误判这种情况。
解决方案1:返回格式化后的字符串(推荐,满足预期格式需求)
如果需要直接返回带指定精度的格式结果,应该将方法返回类型改为String,使用String.format完成格式化:
// 默认精度为2的重载方法 public static String TrianglePerimeter(int a, int b, int c) { return TrianglePerimeter(a, b, c, 2); } public static String TrianglePerimeter(int a, int b, int c, int precision) { // 参数合法性校验 if (a < 0 || b < 0 || c < 0 || precision < 2 || precision > 8) throw new IllegalArgumentException("wrong arguments"); // 有效三角形判断 if (a + b <= c || a + c <= b || b + c <= a) throw new IllegalArgumentException("object not exist"); double perimeter = (double) a + b + c; // 格式化指定精度,自动补全末尾的零 return String.format("%." + precision + "f", perimeter); }
调用示例:
System.out.println(TrianglePerimeter(1, 2, 3, 3)); // 输出 6.000 System.out.println(TrianglePerimeter(1, 1, 1, 5)); // 输出 3.00000
解决方案2:返回double类型(仅保证数值精度,展示时再格式化)
如果必须返回数值类型(double),Math.Round的使用逻辑是正确的,但需要在展示结果时进行格式化:
// 默认精度为2的重载方法 public static double TrianglePerimeter(int a, int b, int c) { return TrianglePerimeter(a, b, c, 2); } public static double TrianglePerimeter(int a, int b, int c, int precision) { if (a < 0 || b < 0 || c < 0 || precision < 2 || precision > 8) throw new IllegalArgumentException("wrong arguments"); if (a + b <= c || a + c <= b || b + c <= a) throw new IllegalArgumentException("object not exist"); double perimeter = (double) a + b + c; // 确保数值精度符合要求 return Math.round(perimeter * Math.pow(10, precision)) / Math.pow(10, precision); }
调用后展示时格式化:
double result1 = TrianglePerimeter(1, 2, 3, 3); System.out.printf("%.3f%n", result1); // 输出 6.000 double result2 = TrianglePerimeter(1, 1, 1, 5); System.out.printf("%.5f%n", result2); // 输出 3.00000
内容的提问来源于stack exchange,提问作者Dominik
相关产品推荐
相关产品推荐

