Dón*_*nal 18 java rounding bigdecimal
我想弄清楚如何将货币金额向上舍入到最接近的5美分.以下显示了我的预期结果
1.03 => 1.05
1.051 => 1.10
1.05 => 1.05
1.900001 => 1.10
Run Code Online (Sandbox Code Playgroud)
我需要结果的精度为2(如上所示).
按照下面的建议,我能做的最好的就是这个
BigDecimal amount = new BigDecimal(990.49)
// To round to the nearest .05, multiply by 20, round to the nearest integer, then divide by 20
def result = new BigDecimal(Math.ceil(amount.doubleValue() * 20) / 20)
result.setScale(2, RoundingMode.HALF_UP)
Run Code Online (Sandbox Code Playgroud)
我不相信这是100%犹太人 - 我担心转换到双打时精度可能会丢失.然而,这是迄今为止我提出的最好的,似乎有效.
rob*_*nst 58
使用BigDecimal没有任何双打(改进了marcolopes的答案):
public static BigDecimal round(BigDecimal value, BigDecimal increment,
RoundingMode roundingMode) {
if (increment.signum() == 0) {
// 0 increment does not make much sense, but prevent division by 0
return value;
} else {
BigDecimal divided = value.divide(increment, 0, roundingMode);
BigDecimal result = divided.multiply(increment);
return result;
}
}
Run Code Online (Sandbox Code Playgroud)
舍入模式例如是RoundingMode.HALF_UP.对于你的例子,你真的想要RoundingMode.UP(bd是一个只返回的助手new BigDecimal(input)):
assertEquals(bd("1.05"), round(bd("1.03"), bd("0.05"), RoundingMode.UP));
assertEquals(bd("1.10"), round(bd("1.051"), bd("0.05"), RoundingMode.UP));
assertEquals(bd("1.05"), round(bd("1.05"), bd("0.05"), RoundingMode.UP));
assertEquals(bd("1.95"), round(bd("1.900001"), bd("0.05"), RoundingMode.UP));
Run Code Online (Sandbox Code Playgroud)
另请注意,您的上一个示例中存在错误(将1.900001舍入到1.10).
我几年前用Java写过这个:https://github.com/marcolopes/dma/blob/master/org.dma.java/src/org/dma/java/math/BusinessRules.java
/**
* Rounds the number to the nearest<br>
* Numbers can be with or without decimals<br>
*/
public static BigDecimal round(BigDecimal value, BigDecimal rounding, RoundingMode roundingMode){
return rounding.signum()==0 ? value :
(value.divide(rounding,0,roundingMode)).multiply(rounding);
}
/**
* Rounds the number to the nearest<br>
* Numbers can be with or without decimals<br>
* Example: 5, 10 = 10
*<p>
* HALF_UP<br>
* Rounding mode to round towards "nearest neighbor" unless
* both neighbors are equidistant, in which case round up.
* Behaves as for RoundingMode.UP if the discarded fraction is >= 0.5;
* otherwise, behaves as for RoundingMode.DOWN.
* Note that this is the rounding mode commonly taught at school.
*/
public static BigDecimal roundUp(BigDecimal value, BigDecimal rounding){
return round(value, rounding, RoundingMode.HALF_UP);
}
/**
* Rounds the number to the nearest<br>
* Numbers can be with or without decimals<br>
* Example: 5, 10 = 0
*<p>
* HALF_DOWN<br>
* Rounding mode to round towards "nearest neighbor" unless
* both neighbors are equidistant, in which case round down.
* Behaves as for RoundingMode.UP if the discarded fraction is > 0.5;
* otherwise, behaves as for RoundingMode.DOWN.
*/
public static BigDecimal roundDown(BigDecimal value, BigDecimal rounding){
return round(value, rounding, RoundingMode.HALF_DOWN);
}
Run Code Online (Sandbox Code Playgroud)
Pet*_*rey -3
您可以使用普通 double 来执行此操作。
double amount = 990.49;
double rounded = ((double) (long) (amount * 20 + 0.5)) / 20;
Run Code Online (Sandbox Code Playgroud)
编辑:对于负数,您需要减去 0.5