如何计算 BigDecimal 中的数字?
How to count digits in BigDecimal?
我正在处理 Java 中的 BigDecimal
,我需要对 DTO 中的 BigDecimal
字段进行 2 次检查:
- 完整部分的位数(点前)< 15
- 总人数
数字 < 32,包括小数位数(小数点后为零)
实现它的最佳方法是什么?我非常不想要 toBigInteger().toString()
和 .toString()
我认为这会奏效。
BigDecimal d = new BigDecimal("921229392299229.2922929292920000");
int fractionCount = d.scale();
System.out.println(fractionCount);
int wholeCount = (int) (Math.ceil(Math.log10(d.longValue())));
System.out.println(wholeCount);
我对上述方法做了一些测试,对比使用 indexOf
和减去 lengths of strings
。如果我的测试方法是合理的,上面的方法似乎明显更快。这是我的测试方法。
Random r = new Random(29);
int nRuns = 1_000_000;
// create a list of 1 million BigDecimals
List<BigDecimal> testData = new ArrayList<>();
for (int j = 0; j < nRuns; j++) {
String wholePart = r.ints(r.nextInt(15) + 1, 0, 10).mapToObj(
String::valueOf).collect(Collectors.joining());
String fractionalPart = r.ints(r.nextInt(31) + 1, 0, 10).mapToObj(
String::valueOf).collect(Collectors.joining());
BigDecimal d = new BigDecimal(wholePart + "." + fractionalPart);
testData.add(d);
}
long start = System.nanoTime();
// Using math
for (BigDecimal d : testData) {
int fractionCount = d.scale();
int wholeCount = (int) (Math.ceil(Math.log10(d.longValue())));
}
long time = System.nanoTime() - start;
System.out.println(time / 1_000_000.);
start = System.nanoTime();
//Using strings
for (BigDecimal d : testData) {
String sd = d.toPlainString();
int n = sd.indexOf(".");
int m = sd.length() - n - 1;
}
time = System.nanoTime() - start;
System.out.println(time / 1_000_000.);
}
我正在处理 Java 中的 BigDecimal
,我需要对 DTO 中的 BigDecimal
字段进行 2 次检查:
- 完整部分的位数(点前)< 15
- 总人数 数字 < 32,包括小数位数(小数点后为零)
实现它的最佳方法是什么?我非常不想要 toBigInteger().toString()
和 .toString()
我认为这会奏效。
BigDecimal d = new BigDecimal("921229392299229.2922929292920000");
int fractionCount = d.scale();
System.out.println(fractionCount);
int wholeCount = (int) (Math.ceil(Math.log10(d.longValue())));
System.out.println(wholeCount);
我对上述方法做了一些测试,对比使用 indexOf
和减去 lengths of strings
。如果我的测试方法是合理的,上面的方法似乎明显更快。这是我的测试方法。
Random r = new Random(29);
int nRuns = 1_000_000;
// create a list of 1 million BigDecimals
List<BigDecimal> testData = new ArrayList<>();
for (int j = 0; j < nRuns; j++) {
String wholePart = r.ints(r.nextInt(15) + 1, 0, 10).mapToObj(
String::valueOf).collect(Collectors.joining());
String fractionalPart = r.ints(r.nextInt(31) + 1, 0, 10).mapToObj(
String::valueOf).collect(Collectors.joining());
BigDecimal d = new BigDecimal(wholePart + "." + fractionalPart);
testData.add(d);
}
long start = System.nanoTime();
// Using math
for (BigDecimal d : testData) {
int fractionCount = d.scale();
int wholeCount = (int) (Math.ceil(Math.log10(d.longValue())));
}
long time = System.nanoTime() - start;
System.out.println(time / 1_000_000.);
start = System.nanoTime();
//Using strings
for (BigDecimal d : testData) {
String sd = d.toPlainString();
int n = sd.indexOf(".");
int m = sd.length() - n - 1;
}
time = System.nanoTime() - start;
System.out.println(time / 1_000_000.);
}