[英]Java, BigDecimal: How do I unit-test for rounding errors?
我將簡要介紹一下我的實際情況:
假設我必須用Java實現一些代碼來計算加權算術平均值 。 我給出了兩個浮點值數組(表示為雙精度數),每個數組長度相同,第一個包含值,第二個包含各自的權重。
我們還說我做了一些實現,它返回一個表示輸入值的加權算術平均值的浮點值(也是一個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個權重。
我的問題是:
在編寫單元測試時,你總是不得不放棄某個地方。 訣竅是當你有足夠的信心時放棄:-)
在您的情況下,一些簡單的測試用例是:
BigDecimal
輸入數組)來計算所選輸入的誤差范圍 比較結果時,使用assertEquals(double, double, double)
,其中前兩個是要比較的值,最后一個是精度(逗號后3個數字為1e-3
)。
最后,您需要使用該算法並查看其行為方式。 當您發現問題時,請為此特定情況添加測試用例。
是的你應該。 測試(應該)總是涉及邊界值。
您可以提供一個epsilon邊界,您斷言答案是(大致)正確的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.