简体   繁体   中英

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

With following operation I translate memory percentage to memory in MB. Percentage memory is calculated with respect to 4096 MB memory. First lets say 80% of 4096 MB memory is needed =>

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

Now this 3276 MB value is stored in storage.

Now next time when I fetch this 3276 MB value from storage and again translate it to percentage memory, I get memory percentage as 79% due to following calculation and integer rounding off

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

So there is this percentage mismatch eg 80% to 79% due to integer rounding off.

How can I avoid this mismatch happening in my java program by correct integer rounding? Is there some generic solution to this problem?

Any way you round is going to have issues like that, changing rounding strategies is just going to change what cases cause them. Once you've lost that precision, you can't get it back. If you want both numbers to be persistent, save both numbers.

tl;dr

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

3277

Rounding with BigDecimal

Specify rounding mode by using BigDecimal .

        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 ) ;

See this code run live at IdeOne.com .

You get your desired result of 3277 .

0.8
3276.8
3277
3277

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM