訂單含多商品,使用滿減券(如減 100 元),需按商品價格比例分攤至各商品,高價商品多分攤,總和精確等於優惠金額,無分攤誤差。
itemAmt = round(totalCoupon * itemPrice / totalPrice, 2)。sumAllocated。diff = couponAmount - sumAllocated(可能為 ±0.01 等)。lastItemAmt += diff。List- items = ...;
double totalPrice = items.stream().mapToDouble(i -> i.price).sum();
double coupon = 100.0;
double allocatedSum = 0;
for (int i = 0; i < items.size(); i++) {
double amt = Math.round(coupon * items.get(i).price / totalPrice * 100) / 100.0;
items.get(i).discount = amt;
allocatedSum += amt;
if (i == items.size() - 1) { // 最後一項吸收尾差
items.get(i).discount += Math.round((coupon - allocatedSum) * 100) / 100.0;
}
}
BigDecimal 替代 double 進行貨幣運算,避免浮點精度問題。Σ discount == coupon 精確成立。此法廣泛應用於電商訂單優惠分攤、分賬結算系統。