由于整数四舍五入,百分比值与绝对值的转换会导致不匹配

Percentage value to absolute value and vice versa translation causes mismatch due to integer rounding off

通过以下操作,我将内存百分比转换为以 MB 为单位的内存。内存百分比是根据 4096 MB 内存计算的。首先假设需要 80%4096 MB 内存 =>

4096*.8 = 3,276.8 ~ rounded to 3,276 MB due to integer operation

现在这个 3276 MB 的值存储在存储器中。

现在,下次当我从存储中获取此 3276 MB 值并再次将其转换为百分比内存时,由于以下计算和整数四舍五入,我得到的内存百分比为 79%

3276*100/4096 = 79.98046875 ~ rounded to 79 % due to integer operation

所以这个百分比不匹配,例如80%79% 由于整数四舍五入。

如何通过正确的整数舍入来避免在我的 java 程序中发生这种不匹配?这个问题有一些通用的解决方案吗?

tl;博士

new BigDecimal( "4096" )
.multiply( new BigDecimal( "0.8" ) )
.setScale( 0 , RoundingMode.HALF_EVEN )
.intValueExact()

3277

四舍五入BigDecimal

使用 BigDecimal 指定 rounding mode

        BigDecimal eightyPercent = new BigDecimal( "0.8" ) ;
        BigDecimal bd = new BigDecimal( "4096" ).multiply( eightyPercent ) ;  
        BigDecimal rounded = bd.setScale( 0 , RoundingMode.HALF_EVEN ) ;  // Bankers rounding.
        int result = rounded.intValueExact() ;  // Throws exception if not fitting into an `int` with no data loss.

        System.out.println( eightyPercent ) ;
        System.out.println( bd ) ;
        System.out.println( rounded ) ;
        System.out.println( result ) ;

看到这个code run live at IdeOne.com

您得到了 3277 想要的结果。

0.8
3276.8
3277
3277

任何舍入方式都会出现这样的问题,改变舍入策略只会改变导致问题的原因。一旦失去精度,就无法恢复。如果您希望这两个数字都保持不变,请保存这两个数字。