mirror of
https://gitee.com/dromara/hutool.git
synced 2026-02-09 09:16:26 +08:00
add NumberFormatUtil
This commit is contained in:
@@ -0,0 +1,162 @@
|
||||
/*
|
||||
* Copyright (c) 2026 Hutool Team.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package cn.hutool.v7.core.math;
|
||||
|
||||
import cn.hutool.v7.core.convert.ConvertUtil;
|
||||
import cn.hutool.v7.core.text.StrUtil;
|
||||
import cn.hutool.v7.core.util.ObjUtil;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.NumberFormat;
|
||||
import java.text.ParsePosition;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* 基于NumberFormat封装的数字格式化/解析工具类
|
||||
* 提供常用的数字格式化、字符串解析为数字的方法,包含异常处理和参数校验
|
||||
*
|
||||
* @author Looly
|
||||
* @since 7.0.0
|
||||
*/
|
||||
public class NumberFormatUtil {
|
||||
|
||||
/**
|
||||
* 默认区域
|
||||
*/
|
||||
private static final Locale DEFAULT_LOCALE = Locale.getDefault(Locale.Category.FORMAT);
|
||||
|
||||
// region ----- format
|
||||
|
||||
/**
|
||||
* 使用默认区域(Locale.getDefault(Locale.Category.FORMAT))格式化数字
|
||||
*
|
||||
* @param number 要格式化的数字(支持Number子类:Integer/Long/Double/BigDecimal等)
|
||||
* @return 格式化后的字符串,null返回空字符串
|
||||
*/
|
||||
public static String format(final Number number) {
|
||||
return format(number, DEFAULT_LOCALE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定区域格式化数字
|
||||
*
|
||||
* @param number 要格式化的数字
|
||||
* @param locale 区域(如Locale.US、Locale.CHINA)
|
||||
* @return 格式化后的字符串,null返回空字符串
|
||||
*/
|
||||
public static String format(final Number number, final Locale locale) {
|
||||
if (number == null) {
|
||||
return "";
|
||||
}
|
||||
final NumberFormat nf = NumberFormat.getInstance(locale);
|
||||
return nf.format(number);
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化数字并指定小数位数
|
||||
*
|
||||
* @param number 要格式化的数字
|
||||
* @param fractionDigits 小数位数(>=0)
|
||||
* @return 格式化后的字符串
|
||||
*/
|
||||
public static String format(final Number number, final int fractionDigits) {
|
||||
return format(number, fractionDigits, Locale.getDefault());
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定区域和小数位数格式化数字
|
||||
*
|
||||
* @param number 要格式化的数字
|
||||
* @param fractionDigits 小数位数(>=0)
|
||||
* @param locale 区域
|
||||
* @return 格式化后的字符串
|
||||
*/
|
||||
public static String format(final Number number, final int fractionDigits, final Locale locale) {
|
||||
if (number == null) {
|
||||
return "";
|
||||
}
|
||||
if (fractionDigits < 0) {
|
||||
throw new IllegalArgumentException("fractionDigits must be >=0:" + fractionDigits);
|
||||
}
|
||||
final NumberFormat nf = NumberFormat.getInstance(locale);
|
||||
nf.setMaximumFractionDigits(fractionDigits);
|
||||
nf.setMinimumFractionDigits(fractionDigits);
|
||||
return nf.format(number);
|
||||
}
|
||||
// endregion
|
||||
|
||||
// region ----- parse
|
||||
|
||||
/**
|
||||
* 使用默认区域解析字符串为数字(返回BigDecimal,避免精度丢失)
|
||||
*
|
||||
* @param source 要解析的字符串(如"1,234.56"、"1234.56")
|
||||
* @return 解析后的BigDecimal,解析失败返回null
|
||||
*/
|
||||
public static Number parse(final String source) {
|
||||
return parse(source, DEFAULT_LOCALE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定区域解析字符串为数字
|
||||
*
|
||||
* @param source 要解析的字符串
|
||||
* @param locale 区域(解析时匹配对应格式,如Locale.US解析"1,234.56")
|
||||
* @return 解析后的BigDecimal,解析失败返回null
|
||||
*/
|
||||
public static Number parse(String source, final Locale locale) {
|
||||
// 参数校验
|
||||
source = StrUtil.trim( source);
|
||||
if(StrUtil.isEmpty(source)){
|
||||
return null;
|
||||
}
|
||||
|
||||
// issue#I79VS7 去除头部加号
|
||||
source = StrUtil.removeAllPrefix(source, "+");
|
||||
|
||||
// issue@4197@Github 转为半角
|
||||
source = ConvertUtil.toDBC(source);
|
||||
|
||||
// issue#IDJ1NS@Gitee 处理科学计数法E+格式
|
||||
// NumberFormat对E+格式支持不佳,使用BigDecimal直接解析
|
||||
if (StrUtil.containsIgnoreCase(source, "e")) {
|
||||
try {
|
||||
return new BigDecimal(source);
|
||||
} catch (final NumberFormatException e) {
|
||||
// BigDecimal解析失败,继续使用NumberFormat尝试
|
||||
}
|
||||
}
|
||||
|
||||
final NumberFormat nf = NumberFormat.getInstance(ObjUtil.defaultIfNull(locale, DEFAULT_LOCALE));
|
||||
if (nf instanceof DecimalFormat) {
|
||||
// issue#1818@Github
|
||||
// 当字符串数字超出double的长度时,会导致截断,此处使用BigDecimal接收
|
||||
((DecimalFormat) nf).setParseBigDecimal(true);
|
||||
}
|
||||
|
||||
final ParsePosition pos = new ParsePosition(0);
|
||||
final Number result = nf.parse(source, pos);
|
||||
|
||||
// 校验解析是否完全成功(pos.getIndex()等于字符串长度才是完全解析)
|
||||
if (result == null || pos.getIndex() != source.length()) {
|
||||
throw new NumberFormatException("Unparseable number: [" + source + "] at: " + pos.getIndex());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
// endregion
|
||||
}
|
||||
@@ -17,11 +17,9 @@
|
||||
package cn.hutool.v7.core.math;
|
||||
|
||||
import cn.hutool.v7.core.array.ArrayUtil;
|
||||
import cn.hutool.v7.core.convert.ConvertUtil;
|
||||
import cn.hutool.v7.core.text.CharUtil;
|
||||
import cn.hutool.v7.core.text.StrUtil;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.NumberFormat;
|
||||
@@ -212,7 +210,9 @@ public class NumberParser {
|
||||
* @param numberStr 数字字符串
|
||||
* @return long
|
||||
*/
|
||||
public long parseLong(final String numberStr) {
|
||||
public long parseLong(String numberStr) {
|
||||
// 去除类型标记
|
||||
numberStr = StrUtil.removeSuffixIgnoreCase(numberStr, "L");
|
||||
if (isBlankOrNaN(numberStr)) {
|
||||
return 0;
|
||||
}
|
||||
@@ -243,7 +243,9 @@ public class NumberParser {
|
||||
* @return long
|
||||
* @since 5.5.5
|
||||
*/
|
||||
public float parseFloat(final String numberStr) {
|
||||
public float parseFloat(String numberStr) {
|
||||
// 去除类型标记
|
||||
numberStr = StrUtil.removeSuffixIgnoreCase(numberStr, "F");
|
||||
if (isBlankOrNaN(numberStr)) {
|
||||
return 0;
|
||||
}
|
||||
@@ -269,7 +271,9 @@ public class NumberParser {
|
||||
* @param numberStr 数字字符串
|
||||
* @return double
|
||||
*/
|
||||
public double parseDouble(final String numberStr) {
|
||||
public double parseDouble(String numberStr) {
|
||||
// 去除类型标记
|
||||
numberStr = StrUtil.removeSuffixIgnoreCase(numberStr, "D");
|
||||
if (isBlankOrNaN(numberStr)) {
|
||||
return 0;
|
||||
}
|
||||
@@ -347,13 +351,20 @@ public class NumberParser {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 16进制
|
||||
// 16进制,需要在结尾标识解析前判断16进制,如0xFF表示16进制数,末尾的F并不能标识类型
|
||||
if (StrUtil.startWithIgnoreCase(numberStr, "0x")) {
|
||||
// 0x04表示16进制数
|
||||
return Long.parseLong(numberStr.substring(2), 16);
|
||||
return parseLong(numberStr);
|
||||
}
|
||||
|
||||
return doParse(numberStr);
|
||||
// 以特殊字母结尾的数字,按照其对应类型解析返回
|
||||
final char lastChar = Character.toUpperCase(numberStr.charAt(numberStr.length() - 1));
|
||||
return switch (lastChar) {
|
||||
case 'F' -> parseFloat(numberStr);
|
||||
case 'D' -> parseDouble(numberStr);
|
||||
case 'L' -> parseLong(numberStr);
|
||||
default -> doParse(numberStr);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -362,42 +373,8 @@ public class NumberParser {
|
||||
*
|
||||
* @return 数字
|
||||
*/
|
||||
private Number doParse(String numberStr) {
|
||||
Locale locale = this.locale;
|
||||
if (null == locale) {
|
||||
locale = Locale.getDefault(Locale.Category.FORMAT);
|
||||
}
|
||||
if (StrUtil.startWith(numberStr, CharUtil.PLUS)) {
|
||||
// issue#I79VS7
|
||||
numberStr = StrUtil.subSuf(numberStr, 1);
|
||||
}
|
||||
|
||||
// issue@4197@Github 转为半角
|
||||
numberStr = ConvertUtil.toDBC(numberStr);
|
||||
|
||||
// issue#IDJ1NS@Gitee 处理科学计数法E+格式
|
||||
// NumberFormat对E+格式支持不佳,使用BigDecimal直接解析
|
||||
if (StrUtil.containsIgnoreCase(numberStr, "e")) {
|
||||
try {
|
||||
return new BigDecimal(numberStr);
|
||||
} catch (final NumberFormatException e) {
|
||||
// BigDecimal解析失败,继续使用NumberFormat尝试
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
final NumberFormat format = NumberFormat.getInstance(locale);
|
||||
if (format instanceof DecimalFormat) {
|
||||
// issue#1818@Github
|
||||
// 当字符串数字超出double的长度时,会导致截断,此处使用BigDecimal接收
|
||||
((DecimalFormat) format).setParseBigDecimal(true);
|
||||
}
|
||||
return format.parse(numberStr);
|
||||
} catch (final ParseException e) {
|
||||
final NumberFormatException nfe = new NumberFormatException(e.getMessage());
|
||||
nfe.initCause(e);
|
||||
throw nfe;
|
||||
}
|
||||
private Number doParse(final String numberStr) {
|
||||
return NumberFormatUtil.parse(numberStr, this.locale);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -16,9 +16,10 @@
|
||||
|
||||
package cn.hutool.v7.core.convert;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
|
||||
/**
|
||||
* https://github.com/chinabugotech/hutool/issues/3105
|
||||
*/
|
||||
@@ -26,6 +27,6 @@ public class Issue3105Test {
|
||||
@Test
|
||||
void toLongTest() {
|
||||
final Long aLong = ConvertUtil.toLong("0.a");
|
||||
Assertions.assertEquals(0L, aLong);
|
||||
assertNull(aLong);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,9 +22,12 @@ import org.junit.jupiter.api.Test;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
public class IssueIALV38Test {
|
||||
|
||||
/**
|
||||
* V7版本变更,旧版本不会抛出异常,新版本中无法解析非正常数字
|
||||
*/
|
||||
@Test
|
||||
void name() {
|
||||
final Object o = ConvertUtil.convertWithCheck(BigDecimal.class, " 111啊", null, false);
|
||||
Assertions.assertEquals(new BigDecimal("111"), o);
|
||||
void convertWithCheckTest() {
|
||||
Assertions.assertThrows(NumberFormatException.class, ()-> ConvertUtil.convertWithCheck(BigDecimal.class, " 111啊", null, false));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package cn.hutool.v7.core.math;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
@@ -25,8 +24,8 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
public class NumberParserTest {
|
||||
@Test
|
||||
void parseLongTest() {
|
||||
final long value = NumberParser.INSTANCE.parseLong("0.a");
|
||||
Assertions.assertEquals(0L, value);
|
||||
// 0.a是非法数字,抛出NumberFormatException
|
||||
assertThrows(NumberFormatException.class, () -> NumberParser.INSTANCE.parseLong("0.a"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -108,14 +108,14 @@ public class NumberUtilTest {
|
||||
@Test
|
||||
public void isIntegerTest() {
|
||||
final String[] validNumArr = {"0", "-0", "+0", "12", "+12", "1234567890", "2147483647", "-2147483648",
|
||||
"0x012345678", "0X012345678", "0xabcdef", "-0xabcdef", "0x12abcdef", "0x7FFFFFFF", "-0x80000000",
|
||||
"01234567", "017777777777", "-020000000000"
|
||||
"0x012345678", "0X012345678", "0xabcdef", "-0xabcdef", "0x12abcdef", "0x7FFFFFFF", "-0x80000000",
|
||||
"01234567", "017777777777", "-020000000000"
|
||||
};
|
||||
privateIsIntegerTest(validNumArr, true);
|
||||
|
||||
final String[] invalidNumArr = {null, "", " ", "+", "+1.", ".1", "99L", "99D", "99F", "12.3", "123e1", "-12.3", "1.2.3",
|
||||
"2147483648", "0x80000000", "020000000000", "-2147483649", "-0x80000001", "-020000000001", "-020000000001",
|
||||
"a", "+a", "123abc", "09"
|
||||
"2147483648", "0x80000000", "020000000000", "-2147483649", "-0x80000001", "-020000000001", "-020000000001",
|
||||
"a", "+a", "123abc", "09"
|
||||
};
|
||||
privateIsIntegerTest(invalidNumArr, false);
|
||||
}
|
||||
@@ -129,20 +129,20 @@ public class NumberUtilTest {
|
||||
@Test
|
||||
public void isLongTest() {
|
||||
final String[] validNumArr = {
|
||||
"0", "0L", "-0L", "+0L", "12", "+12", "1234567890123456789", "99L",
|
||||
"2147483648", "0x80000000", "020000000000", "-2147483649", "-0x80000001", "-020000000001", "-020000000001",
|
||||
"9223372036854775807", "-9223372036854775808",
|
||||
"0x0123456789", "0X0123456789", "0x123456789abcdef", "0xabcdef123456789", "0x7FFFFFFF", "-0x80000000",
|
||||
"0x7fffffffffffffff", "-0x8000000000000000",
|
||||
"01234567", "0777777777777777777777", "-01000000000000000000000"
|
||||
"0", "0L", "-0L", "+0L", "12", "+12", "1234567890123456789", "99L",
|
||||
"2147483648", "0x80000000", "020000000000", "-2147483649", "-0x80000001", "-020000000001", "-020000000001",
|
||||
"9223372036854775807", "-9223372036854775808",
|
||||
"0x0123456789", "0X0123456789", "0x123456789abcdef", "0xabcdef123456789", "0x7FFFFFFF", "-0x80000000",
|
||||
"0x7fffffffffffffff", "-0x8000000000000000",
|
||||
"01234567", "0777777777777777777777", "-01000000000000000000000"
|
||||
};
|
||||
privateIsLongTest(validNumArr, true);
|
||||
|
||||
final String[] invalidNumArr = {null, "", " ", "+", "+1.", ".1", "99D", "99F", "12.3", "123e1", "-12.3", "1.2.3",
|
||||
"a", "+a", "123abc", "09",
|
||||
"9223372036854775808", "-9223372036854775809",
|
||||
"0x8000000000000000", "-0x8000000000000001",
|
||||
"01000000000000000000000", "-01000000000000000000001"
|
||||
"a", "+a", "123abc", "09",
|
||||
"9223372036854775808", "-9223372036854775809",
|
||||
"0x8000000000000000", "-0x8000000000000001",
|
||||
"01000000000000000000000", "-01000000000000000000001"
|
||||
};
|
||||
privateIsLongTest(invalidNumArr, false);
|
||||
}
|
||||
@@ -322,7 +322,7 @@ public class NumberUtilTest {
|
||||
|
||||
@Test
|
||||
public void decimalFormatNaNTest() {
|
||||
assertThrows(IllegalArgumentException.class, ()->{
|
||||
assertThrows(IllegalArgumentException.class, () -> {
|
||||
final Double a = 0D;
|
||||
final Double b = 0D;
|
||||
|
||||
@@ -333,7 +333,7 @@ public class NumberUtilTest {
|
||||
|
||||
@Test
|
||||
public void decimalFormatNaNTest2() {
|
||||
assertThrows(IllegalArgumentException.class, ()->{
|
||||
assertThrows(IllegalArgumentException.class, () -> {
|
||||
final Double a = 0D;
|
||||
final Double b = 0D;
|
||||
|
||||
@@ -384,21 +384,20 @@ public class NumberUtilTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void emptyToBigDecimalTest(){
|
||||
assertThrows(IllegalArgumentException.class,()-> NumberUtil.toBigDecimal(""));
|
||||
void emptyToBigDecimalTest() {
|
||||
assertThrows(IllegalArgumentException.class, () -> NumberUtil.toBigDecimal(""));
|
||||
}
|
||||
|
||||
@Test
|
||||
void naNToBigDecimalTest(){
|
||||
void naNToBigDecimalTest() {
|
||||
assertEquals(BigDecimal.ZERO, NumberUtil.toBigDecimal("NaN"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void issue2878Test() throws ParseException {
|
||||
// https://github.com/chinabugotech/hutool/issues/2878
|
||||
// 当数字中包含一些非数字字符时,按照JDK的规则,不做修改。
|
||||
final BigDecimal bigDecimal = NumberUtil.toBigDecimal("345.sdf");
|
||||
assertEquals(NumberFormat.getInstance().parse("345.sdf"), bigDecimal.longValue());
|
||||
// 当数字中包含一些非数字字符时,V7版本中抛出异常
|
||||
assertThrows(NumberFormatException.class, () -> NumberUtil.toBigDecimal("345.sdf"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -419,20 +418,18 @@ public class NumberUtilTest {
|
||||
number = NumberUtil.parseInt(" ");
|
||||
assertEquals(0, number);
|
||||
|
||||
number = NumberUtil.parseInt("10F");
|
||||
assertEquals(10, number);
|
||||
|
||||
number = NumberUtil.parseInt("22.4D");
|
||||
assertEquals(22, number);
|
||||
|
||||
number = NumberUtil.parseInt("22.6D");
|
||||
assertEquals(22, number);
|
||||
// 浮点数解析为int时会造成精度丢失
|
||||
assertThrows(NumberFormatException.class, () -> {
|
||||
NumberUtil.parseInt("22.4D");
|
||||
});
|
||||
|
||||
number = NumberUtil.parseInt("0");
|
||||
assertEquals(0, number);
|
||||
|
||||
number = NumberUtil.parseInt(".123");
|
||||
assertEquals(0, number);
|
||||
number = NumberUtil.parseInt(".999");
|
||||
assertEquals(0, number);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -445,7 +442,7 @@ public class NumberUtilTest {
|
||||
|
||||
@Test
|
||||
public void parseIntTest3() {
|
||||
assertThrows(NumberFormatException.class, ()->{
|
||||
assertThrows(NumberFormatException.class, () -> {
|
||||
final int v1 = NumberUtil.parseInt("d");
|
||||
assertEquals(0, v1);
|
||||
});
|
||||
@@ -453,7 +450,7 @@ public class NumberUtilTest {
|
||||
|
||||
@Test
|
||||
public void parseIntTest4() {
|
||||
assertThrows(NumberFormatException.class, ()->{
|
||||
assertThrows(NumberFormatException.class, () -> {
|
||||
// issue#I5M55F
|
||||
// 科学计数法忽略支持,科学计数法一般用于表示非常小和非常大的数字,这类数字转换为int后精度丢失,没有意义。
|
||||
final String numberStr = "429900013E20220812163344551";
|
||||
@@ -471,9 +468,7 @@ public class NumberUtilTest {
|
||||
assertEquals(456, NumberUtil.parseInt("abc", 456));
|
||||
|
||||
// -------------------------- Parse success -----------------------
|
||||
|
||||
assertEquals(123, NumberUtil.parseInt("123.abc", 789));
|
||||
|
||||
assertEquals(789, NumberUtil.parseInt("123.abc", 789));
|
||||
assertEquals(123, NumberUtil.parseInt("123.3", null));
|
||||
|
||||
}
|
||||
@@ -506,7 +501,7 @@ public class NumberUtilTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parseNumberTest3(){
|
||||
public void parseNumberTest3() {
|
||||
|
||||
// -------------------------- Parse failed -----------------------
|
||||
|
||||
@@ -520,16 +515,16 @@ public class NumberUtilTest {
|
||||
|
||||
// -------------------------- Parse success -----------------------
|
||||
|
||||
assertEquals(123, NumberUtil.parseNumber("123.abc", 789).intValue());
|
||||
assertEquals(789, NumberUtil.parseNumber("123.abc", 789).intValue());
|
||||
|
||||
assertEquals(123.3D, NumberUtil.parseNumber("123.3", (Number) null).doubleValue());
|
||||
|
||||
assertEquals(0.123D, NumberUtil.parseNumber("0.123.3", (Number) null).doubleValue());
|
||||
assertNull(NumberUtil.parseNumber("0.123.3", (Number) null));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void issueIDJ1NSTest(){
|
||||
void issueIDJ1NSTest() {
|
||||
final String numberstr1 = "8.37095942E+9";
|
||||
final BigDecimal result1 = (BigDecimal) NumberUtil.parseNumber(numberstr1);
|
||||
final String numberstr2 = "8.37095942e+9";
|
||||
@@ -567,14 +562,15 @@ public class NumberUtilTest {
|
||||
number = NumberUtil.parseLong(" ");
|
||||
assertEquals(0, number);
|
||||
|
||||
number = NumberUtil.parseLong("10F");
|
||||
assertEquals(10, number);
|
||||
// 明确float类型时,解析long报错,避免精度丢失问题
|
||||
assertThrows(NumberFormatException.class, () -> {
|
||||
NumberUtil.parseLong("10F");
|
||||
});
|
||||
|
||||
number = NumberUtil.parseLong("22.4D");
|
||||
assertEquals(22, number);
|
||||
|
||||
number = NumberUtil.parseLong("22.6D");
|
||||
assertEquals(22, number);
|
||||
// 明确double类型时,解析long报错,避免精度丢失问题
|
||||
assertThrows(NumberFormatException.class, () -> {
|
||||
NumberUtil.parseLong("22.4D");
|
||||
});
|
||||
|
||||
number = NumberUtil.parseLong("0");
|
||||
assertEquals(0, number);
|
||||
@@ -702,11 +698,11 @@ public class NumberUtilTest {
|
||||
|
||||
@Test
|
||||
public void rangeMinTest() {
|
||||
assertThrows(NegativeArraySizeException.class, ()-> NumberUtil.range(0, Integer.MIN_VALUE));
|
||||
assertThrows(NegativeArraySizeException.class, () -> NumberUtil.range(0, Integer.MIN_VALUE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isPrimeTest(){
|
||||
public void isPrimeTest() {
|
||||
assertTrue(NumberUtil.isPrime(2));
|
||||
assertTrue(NumberUtil.isPrime(3));
|
||||
assertTrue(NumberUtil.isPrime(7));
|
||||
@@ -718,6 +714,7 @@ public class NumberUtilTest {
|
||||
assertFalse(NumberUtil.isPrime(296733));
|
||||
assertFalse(NumberUtil.isPrime(20_4123_2399));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isPrimeTest2() {
|
||||
assertTrue(NumberUtil.isPrime(2));
|
||||
@@ -743,14 +740,15 @@ public class NumberUtilTest {
|
||||
assertNull(NumberUtil.parseFloat("abc", null));
|
||||
|
||||
assertNull(NumberUtil.parseFloat("a123.33", null));
|
||||
assertNull(NumberUtil.parseFloat("123.33a", null));
|
||||
|
||||
assertNull(NumberUtil.parseFloat("..123", null));
|
||||
|
||||
|
||||
assertEquals(1233F, NumberUtil.parseFloat(StrUtil.EMPTY, 1233F));
|
||||
|
||||
// -------------------------- Parse success -----------------------
|
||||
|
||||
assertEquals(123.33F, NumberUtil.parseFloat("123.33a", null));
|
||||
|
||||
assertEquals(0.123F, NumberUtil.parseFloat(".123", null));
|
||||
|
||||
@@ -766,9 +764,9 @@ public class NumberUtilTest {
|
||||
assertNull(NumberUtil.parseDouble("..123", null));
|
||||
assertEquals(1233D, NumberUtil.parseDouble(StrUtil.EMPTY, 1233D));
|
||||
|
||||
assertThrows(NumberFormatException.class, () -> NumberUtil.parseDouble("123.33a"));
|
||||
// -------------------------- Parse success -----------------------
|
||||
|
||||
assertEquals(123.33D, NumberUtil.parseDouble("123.33a", null));
|
||||
assertEquals(0.123D, NumberUtil.parseDouble(".123", null));
|
||||
}
|
||||
|
||||
@@ -798,10 +796,10 @@ public class NumberUtilTest {
|
||||
|
||||
@Test
|
||||
void nullToZeroTest() {
|
||||
assertEquals(0, NumberUtil.nullToZero((Integer)null));
|
||||
assertEquals(0L, NumberUtil.nullToZero((Long)null));
|
||||
assertEquals(0D, NumberUtil.nullToZero((Double)null));
|
||||
assertEquals(0D, NumberUtil.nullToZero((Double)null));
|
||||
assertEquals(0, NumberUtil.nullToZero((Integer) null));
|
||||
assertEquals(0L, NumberUtil.nullToZero((Long) null));
|
||||
assertEquals(0D, NumberUtil.nullToZero((Double) null));
|
||||
assertEquals(0D, NumberUtil.nullToZero((Double) null));
|
||||
assertEquals(0F, NumberUtil.nullToZero((Float) null));
|
||||
assertEquals(0, NumberUtil.nullToZero((Short) null));
|
||||
assertEquals(0, NumberUtil.nullToZero((Byte) null));
|
||||
|
||||
Reference in New Issue
Block a user