gpt4 book ai didi

Java,BigDecimal : How do I unit-test for rounding errors?

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:46:43 26 4
gpt4 key购买 nike

我举一个我实际情况的简化例子:

假设我必须用 Java 实现一些代码来计算 Weighted arithmetic mean .我得到了两个浮点值数组(表示为 double 值),每个数组的长度都相同,第一个包含值,第二个包含它们各自的权重。

假设我做了一些实现,它返回一个浮点值(也是一个 double 值),表示输入值的加权算术平均值:

public static double calculateWeightedArithmeticMean(double[] values, 
double[] weights) {

if(values.length != weights.length) {
throw new IllegalArgumentException();
}

if(values.length == 0) {
return 0;
}

if(values.length == 1) {
return new BigDecimal(values[0]).setScale(1, RoundingMode.HALF_UP).
doubleValue();
}

BigDecimal dividend = BigDecimal.ZERO;
BigDecimal divisor = BigDecimal.ZERO;
for(int i = 0; i < values.length; i++) {
dividend = dividend.add(new BigDecimal(values[i]).
multiply(new BigDecimal(weights[i])));
divisor = divisor.add(new BigDecimal(weights[i]));
}
if(dividend.compareTo(BigDecimal.ZERO) == 0) {
return 0d;
}
return dividend.divide(divisor, 1, RoundingMode.HALF_UP).doubleValue();
}

我编写了一个传递一些值(例如 3 个值 + 3 个权重)的单元测试。我首先手动计算他们的加权算术平均值(使用计算器),然后编写一个单元测试来检查我的代码是否返回该值。

我认为,由于舍入误差,这种测试不适用于使用的值数量大得多的情况。也许我实现的代码适用于 3 个值 + 3 个权重(对于给定的精度),因为在这种情况下舍入误差小于精度,但舍入误差很可能大于 1000 的所需精度值 + 1000 个权重。

我的问题是:

  • 我是否还应该编写一个单元测试来检查大量值(生产使用的“最坏情况”)?
  • 如果我应该,我该如何写?如何获得正确的值,以便我可以在我的测试断言中使用它(手动计算 2x1000 值的均值似乎是个坏主意,即使使用 Weighted mean calculator ...)?
  • 类似的场景也是如此:计算geometric mean等等……

最佳答案

在编写单元测试时,你总是要在某个地方放弃。诀窍是当您确信自己知道的足够多时就放弃 :-)

在您的案例中,一些简单的测试用例是:

  • 空数组
  • 创建第二个算法,该算法使用精确算术(如 BigDecimal 输入数组)来计算所选输入的误差范围
  • 两个填充相同值的数组。这样,您就知道结果了(它应该与单独的第一对相同)。
    • 尝试找出一对导致较大舍入误差的数字(例如 1/10、0.1/1、0.2/2,它们最终都为 0.1,无法使用 double 表示;see here)
  • 创建包含随机方差(即 +- 1% * rand())的输入数组。随着输入数组的增长,这些应该会平衡。

比较结果时,使用 assertEquals(double, double, double) 其中前两个是要比较的值,最后一个是精度 (1e-3 逗号后的 3 位数字)。

最后,您需要使用该算法并查看其行为方式。当您发现问题时,然后为这个特定案例添加一个测试用例。

关于Java,BigDecimal : How do I unit-test for rounding errors?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26138548/

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