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 e.g. 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?
CodePudding user response:
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.
CodePudding user response:
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