Merge pull request #4136 from ZhonglinGui/v5-dev

修复Validator.isBetween方法在高精度Number类型下存在精度丢失问题
This commit is contained in:
Golden Looly
2025-11-20 10:49:03 +08:00
committed by GitHub
2 changed files with 19 additions and 2 deletions

View File

@@ -9,6 +9,7 @@ import cn.hutool.core.util.ReUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.IdcardUtil;
import java.math.BigDecimal;
import java.net.MalformedURLException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -1123,8 +1124,11 @@ public class Validator {
Assert.notNull(value);
Assert.notNull(min);
Assert.notNull(max);
final double doubleValue = value.doubleValue();
return (doubleValue >= min.doubleValue()) && (doubleValue <= max.doubleValue());
// 通过 NumberUtil 转换为 BigDecimal使用 BigDecimal 进行比较以保留精度
BigDecimal valBd = NumberUtil.toBigDecimal(value);
BigDecimal minBd = NumberUtil.toBigDecimal(min);
BigDecimal maxBd = NumberUtil.toBigDecimal(max);
return valBd.compareTo(minBd) >= 0 && valBd.compareTo(maxBd) <= 0;
}
/**

View File

@@ -227,6 +227,19 @@ public class ValidatorTest {
assertTrue(Validator.isBetween(0.19, 0.1, 0.2));
}
@Test
public void isBetweenPrecisionLossTest() {
// 使用超过 double 精度的值
long base = 10000000000000000L;
long min = base + 1;
long max = base + 2;
// 在 double 转换下base、min 和 max 是完全相等的,因为 double 精度不够
// 预期结果为false但是因为double 精度不够导致输出为true
assertFalse(Validator.isBetween(base, min, max));
}
@Test
public void isCarVinTest() {
assertTrue(Validator.isCarVin("LSJA24U62JG269225"));