Java处理金额四舍五入时触发NumberFormatException异常求助
数值分位四舍五入异常分析与解决
问题重现
代码示例:
double amount = 289.42; String f= String.format("%.1f", amount); System.out.println(new DecimalFormat("##0.00").format(Double.valueOf(f)));
报错信息:java.lang.NumberFormatException: 输入字符串格式错误: "289,4"
报错原因
核心问题是系统区域设置不一致:
String.format("%.1f", amount)会遵循当前系统默认的区域格式生成字符串,如果你的系统是欧洲这类用逗号,作为小数点分隔符的区域,生成的字符串就是"289,4",而非预期的"289.4"。- 后续调用
Double.valueOf(f)时,默认采用英文区域的解析规则,只认点号.作为小数点,遇到逗号自然就会抛出数字格式异常。
解决方案
方案1:跳过冗余字符串转换,直接用数学运算+格式化
不需要转成字符串再解析,直接通过数学运算完成四舍五入,再用DecimalFormat格式化:
double amount = 289.42; // 先四舍五入到1位小数:289.42 *10=2894.2,取整后是2894,除以10得289.4 double rounded = Math.round(amount * 10) / 10.0; System.out.println(new DecimalFormat("##0.00").format(rounded));
方案2:强制指定统一的区域设置
在格式化和解析时都用同一个区域(比如英文区域),确保小数点分隔符一致:
import java.util.Locale; double amount = 289.42; // 指定英文区域,生成带点号的字符串"289.4" String f = String.format(Locale.US, "%.1f", amount); // 正常解析后再格式化 System.out.println(new DecimalFormat("##0.00").format(Double.valueOf(f)));
方案3:用DecimalFormat直接控制四舍五入规则
通过设置DecimalFormat的舍入模式,一步完成四舍五入和格式化:
import java.math.RoundingMode; import java.text.DecimalFormat; double amount = 289.42; DecimalFormat df = new DecimalFormat("##0.00"); // 设置标准四舍五入模式 df.setRoundingMode(RoundingMode.HALF_UP); // 先格式化为1位小数再转成数值,再格式化为两位 double temp = Double.parseDouble(new DecimalFormat("##0.0").format(amount)); System.out.println(df.format(temp));
内容的提问来源于stack exchange,提问作者Francesco Anfuso
相关产品推荐
相关产品推荐

