debugjavaMinor
Java helper function to round a number to the specified number of decimal places
Viewed 0 times
placesnumberthehelperdecimalfunctionjavaroundspecified
Problem
The function I need:
Rounds a double to the specified number of decimal places
I figured this would be a part of
I'd appreciate feedback on the overall strategy, the Javadoc comments, and the naming conventions.
Rounds a double to the specified number of decimal places
I figured this would be a part of
java.lang.math, but inexplicably it doesn't have a round function that returns a double. Thus, my proposed solution is to add my own round function in a MathEx class./**
* Holds generic math functions to extend the capabilities of the java.lang.Math class
*/
public class MathEx {
/**
* Rounds a double to the specified number of decimal places using the ubiquitous "half up" rounding method
* @param numberToRound The number to be rounded
* @param numberOfDecimals The number of decimals to include in the rounded number
* @return The rounded number
*/
public static double round(double numberToRound, int numberOfDecimals) {
return new BigDecimal(numberToRound)
.setScale(numberOfDecimals, BigDecimal.ROUND_HALF_UP)
.doubleValue();
}
}I'd appreciate feedback on the overall strategy, the Javadoc comments, and the naming conventions.
Solution
This question makes assumptions which are not supported by the actual implementations of
Consider the following code:
That code takes an input value
Consider an input value
Now, round that value to 6 decimals, and get:
Then multiply that by 1 billion to get
Unfortunately, the actual result is:
The reason is that
The bottom line?
Rounding floating-point numbers to any fractional value will result in occasional errors.
The solution is to keep everything as a
Here is an ideone, it loops through small values until it finds one which causes errors. The first error it finds is at 65 millionths.
double in Java (or most other languages).double is a floating-point number format, which has a number of odd behaviours that simply do not support 'rounding' in a consistently accurate way.Consider the following code:
double d = (v * 10 + 4) / 10_000_000.0;
double rescale = round(d, 6) * 1_000_000_000.0;That code takes an input value
v, multiplies it by 10, adds 4, and then divides it by 10 million.Consider an input value
65. Take that, multiply by 10, and add 4, to get 654. Now, divide 654 by 10 million, to get 0.0000654.Now, round that value to 6 decimals, and get:
0.0000650, right?Then multiply that by 1 billion to get
65000Unfortunately, the actual result is:
64999.999999999990000000The reason is that
0.000065 does not exist. Sure, many things that print numbers in Java will print a rounded value for you, but any math you do will have small errors inconsistent with your expectations.The bottom line?
Rounding floating-point numbers to any fractional value will result in occasional errors.
The solution is to keep everything as a
BigDecimal number. Do not use your method unless you know what you are sacrificing.Here is an ideone, it loops through small values until it finds one which causes errors. The first error it finds is at 65 millionths.
Code Snippets
double d = (v * 10 + 4) / 10_000_000.0;
double rescale = round(d, 6) * 1_000_000_000.0;64999.999999999990000000Context
StackExchange Code Review Q#85087, answer score: 3
Revisions (0)
No revisions yet.