diff --git a/hutool-core/src/main/java/cn/hutool/core/util/NumberUtil.java b/hutool-core/src/main/java/cn/hutool/core/util/NumberUtil.java index 6f9068495..400c12b91 100644 --- a/hutool-core/src/main/java/cn/hutool/core/util/NumberUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/util/NumberUtil.java @@ -1063,28 +1063,28 @@ public class NumberUtil { * 格式化double
* 对 {@link DecimalFormat} 做封装
* - * @param pattern 格式 格式中主要以 # 和 0 两种占位符号来指定数字长度。0 表示如果位数不足则以 0 填充,# 表示只要有可能就把数字拉上这个位置。
- * - * @param value 值,支持BigDecimal、BigInteger、Number等类型 + * @param pattern 格式 格式中主要以 # 和 0 两种占位符号来指定数字长度。0 表示如果位数不足则以 0 填充,# 表示只要有可能就把数字拉上这个位置。
+ * + * @param value 值,支持BigDecimal、BigInteger、Number等类型 * @param roundingMode 保留小数的方式枚举 * @return 格式化后的值 * @since 5.6.5 */ public static String decimalFormat(String pattern, Object value, RoundingMode roundingMode) { - if(value instanceof Number){ + if (value instanceof Number) { Assert.isTrue(isValidNumber((Number) value), "value is NaN or Infinite!"); } final DecimalFormat decimalFormat = new DecimalFormat(pattern); - if(null != roundingMode){ + if (null != roundingMode) { decimalFormat.setRoundingMode(roundingMode); } return decimalFormat.format(value); @@ -1472,7 +1472,7 @@ public class NumberUtil { * @since 5.6.0 */ public static BigInteger factorial(BigInteger n) { - if(n.equals(BigInteger.ZERO)){ + if (n.equals(BigInteger.ZERO)) { return BigInteger.ONE; } return factorial(n, BigInteger.ZERO); @@ -1492,21 +1492,21 @@ public class NumberUtil { public static BigInteger factorial(BigInteger start, BigInteger end) { Assert.notNull(start, "Factorial start must be not null!"); Assert.notNull(end, "Factorial end must be not null!"); - if(start.compareTo(BigInteger.ZERO) < 0 || end.compareTo(BigInteger.ZERO) < 0){ + if (start.compareTo(BigInteger.ZERO) < 0 || end.compareTo(BigInteger.ZERO) < 0) { throw new IllegalArgumentException(StrUtil.format("Factorial start and end both must be > 0, but got start={}, end={}", start, end)); } - if (start.equals(BigInteger.ZERO)){ + if (start.equals(BigInteger.ZERO)) { start = BigInteger.ONE; } - if(end.compareTo(BigInteger.ONE) < 0){ + if (end.compareTo(BigInteger.ONE) < 0) { end = BigInteger.ONE; } BigInteger result = start; end = end.add(BigInteger.ONE); - while(start.compareTo(end) > 0) { + while (start.compareTo(end) > 0) { start = start.subtract(BigInteger.ONE); result = result.multiply(start); } @@ -2116,7 +2116,7 @@ public class NumberUtil { */ public static String toStr(BigDecimal bigDecimal, boolean isStripTrailingZeros) { Assert.notNull(bigDecimal, "BigDecimal is null !"); - if(isStripTrailingZeros){ + if (isStripTrailingZeros) { bigDecimal = bigDecimal.stripTrailingZeros(); } return bigDecimal.toPlainString(); @@ -2669,10 +2669,26 @@ public class NumberUtil { * @return 结果 * @since 5.7.6 */ - public static double calculate(String expression){ + public static double calculate(String expression) { return Calculator.conversion(expression); } + /** + * Number值转换为double
+ * float强制转换存在精度问题,此方法避免精度丢失 + * + * @param value 被转换的float值 + * @return double值 + * @since 5.7.8 + */ + public static double toDouble(Number value) { + if(value instanceof Float){ + return Double.parseDouble(value.toString()); + }else{ + return value.doubleValue(); + } + } + // ------------------------------------------------------------------------------------------- Private method start private static int mathSubNode(int selectNum, int minNum) { if (selectNum == minNum) { diff --git a/hutool-poi/src/main/java/cn/hutool/poi/excel/cell/setters/NumberCellSetter.java b/hutool-poi/src/main/java/cn/hutool/poi/excel/cell/setters/NumberCellSetter.java index 5f98f8e79..817e52940 100755 --- a/hutool-poi/src/main/java/cn/hutool/poi/excel/cell/setters/NumberCellSetter.java +++ b/hutool-poi/src/main/java/cn/hutool/poi/excel/cell/setters/NumberCellSetter.java @@ -1,5 +1,6 @@ package cn.hutool.poi.excel.cell.setters; +import cn.hutool.core.util.NumberUtil; import cn.hutool.poi.excel.cell.CellSetter; import org.apache.poi.ss.usermodel.Cell; @@ -26,10 +27,6 @@ public class NumberCellSetter implements CellSetter { public void setValue(Cell cell) { // issue https://gitee.com/dromara/hutool/issues/I43U9G // 避免float到double的精度问题 - if (value instanceof Float) { - cell.setCellValue(value.floatValue()); - } else { - cell.setCellValue(value.doubleValue()); - } + cell.setCellValue(NumberUtil.toDouble(value)); } } diff --git a/hutool-poi/src/test/java/cn/hutool/poi/excel/ExcelWriteTest.java b/hutool-poi/src/test/java/cn/hutool/poi/excel/ExcelWriteTest.java index d21f104b8..041349827 100644 --- a/hutool-poi/src/test/java/cn/hutool/poi/excel/ExcelWriteTest.java +++ b/hutool-poi/src/test/java/cn/hutool/poi/excel/ExcelWriteTest.java @@ -721,4 +721,16 @@ public class ExcelWriteTest { writer.close(); } + + @Test + @Ignore + public void writeFloatTest(){ + //issue https://gitee.com/dromara/hutool/issues/I43U9G + String path = "d:/test/floatTest.xlsx"; + FileUtil.del(path); + + final ExcelWriter writer = ExcelUtil.getWriter(path); + writer.writeRow(ListUtil.of(22.9f)); + writer.close(); + } }