gpt4 book ai didi

java - 保持最大精度水平

转载 作者:搜寻专家 更新时间:2023-10-31 20:16:40 25 4
gpt4 key购买 nike

我正在处理一个业务逻辑,我需要对 BigDecimal 变量进行除法和乘法以产生业务结果,但我面临着保持准确性的问题。

实际业务我不能放在这里,所以我创建了一个示例程序并包含在这里。我只需要使用 BigDecimal,所以我对此很严格,但我愿意使用任何比例、模式或任何有助于我获得最大精度的东西。

我们随时欢迎您提出建议。

示例代码

public class Test {
public static void main(String[] args) {
BigDecimal hoursInADay = new BigDecimal("24");
BigDecimal fraction = BigDecimal.ONE.divide(hoursInADay, 3,
RoundingMode.HALF_UP);
BigDecimal count = BigDecimal.ZERO;

for (int i = 1; i <= 24; i++) {
count = count.add(fraction);
}

if (BigDecimal.ONE.equals(count)) {
// accuracy level 100%
}
}
}

最佳答案

只是一个实验(为了好玩),我试图实现这个 Fraction 类,它包装了 BigDecimal 但在需要最终结果之前避免除法。

方法实现基于:

  • 添加:a/b + c/d = (ad + bc)/bd
  • 乘法:(a/b) * (c/d) = ac/bd
  • 划分:(a/b)/(c/d) = ad/bc

未使用它是因为 BigDecimal 的准确性不够,但因为过早除法在非终止值的情况下必然会导致舍入错误。

代码:

class Fraction {

private final BigDecimal numerator;
private final BigDecimal denominator;

public Fraction(BigDecimal numerator, BigDecimal denumerator) {
this.numerator = numerator;
this.denominator = denumerator;
}

public static final Fraction ZERO = new Fraction(BigDecimal.ZERO,
BigDecimal.ONE);
public static final Fraction ONE = new Fraction(BigDecimal.ONE,
BigDecimal.ONE);

public static Fraction of(BigDecimal numerator) {
return new Fraction(numerator, BigDecimal.ONE);
}

public static Fraction of(BigDecimal numerator, BigDecimal denominator) {
return new Fraction(numerator, denominator);
}

public Fraction add(Fraction other) {
return Fraction.of(other.denominator.multiply(this.numerator)
.add(other.numerator.multiply(this.denominator)),
this.denominator.multiply(other.denominator));
}

public Fraction multiply(Fraction other) {
return new Fraction(this.numerator.multiply(other.numerator),
this.denominator.multiply(other.denominator));
}

public Fraction divide(Fraction other) {
return new Fraction(this.numerator.multiply(other.denominator),
this.denominator.multiply(other.numerator));
}

public BigDecimal value() {
try {
return this.numerator.divide(this.denominator);
} catch (ArithmeticException ae) {
return this.numerator.divide(this.denominator, 6,
RoundingMode.HALF_UP);
}
}

@Override
public String toString() {
return String.format("%s/%s", this.numerator, this.denominator);
}
}

并使用它来执行您的原始计算:

public static void main(String[] args) {
Fraction twentyFour = Fraction.of(BigDecimal.valueOf(24));
Fraction fraction = Fraction.ONE.divide(twentyFour);
System.out.println("Fraction = " + fraction);

Fraction count = new Fraction(BigDecimal.ZERO, BigDecimal.ONE);
for (int i = 1; i <= 24; i++) {
count = count.add(fraction);
}

if (BigDecimal.ONE.equals(count.value())) {
System.out.println("100%");
} else {
System.out.println(count);
}
}

输出:

Fraction = 1/24
100%

重要的是要注意,这绝不是优化的。例如,分数简化(1/24 + 1/24 将存储为 48/576 而不是 1/12,这可能具有不可忽略的存储和计算成本)

关于java - 保持最大精度水平,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55703405/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com