patternjavaMinor
Floating point equality in Java - follow-up
Viewed 0 times
equalitypointfloatingjavafollow
Problem
This is a follow up post for this question.
There aren't a lot of changes. The changes (all of them major) are:
Basically, I fix my code when someone manages to break it. Tom Leek opened my eyes. Spotted's answer was nice too, but it's too bad that it must be done in a slightly different way to ensure compilation. It was a nice feeling when I saw my code pass in the cases mentioned by Tom Leek.
```
package library.util;
/**
* This class provides a useful interface for easy (approximate) floating
* point equality checks. This is necessary for several other classes. This
* class provides the user the power to set custom values for the
* tolerances used in comparison.
*
* @author Subhomoy Haldar (ambigram_maker)
* @version 1.5
*/
public class Numbers {
/**
* Private constructor to prevent instantiation.
*/
private Numbers() {
throw new AssertionError("No instances for you! ;P");
}
/**
* The default tolerance value for comparing the {@code float} values.
*/
public static final float DEFAULT_FLOAT_TOLERANCE = 5E-8f;
/**
* The default tolerance value for comparing the {@code double} values.
*/
public static final double DEFAULT_DOUBLE_TOLERANCE = 5E-16;
/**
* The current tolerance to be used for comparing floats.
*/
private static float floatTolerance = DEFAULT_FLOAT_TOLERANCE;
/**
* The current tolerance to be used for comparing doubles.
*/
private static double doubleTolerance =
There aren't a lot of changes. The changes (all of them major) are:
- I've decided to ditch my previous approach using
Math.ulp()and adopt Tim Leek's suggestion: comparing ratios. In my updated code, I calculate both ratios and ensure that their difference from 1 is within the tolerance.
- The flexibility of the class is still kept in mind; getters and setters have been added to compliment the
private statictolerance values.
- The constructor is made
privateto prevent instantiation (which I simply forgot about in the previous version).
Basically, I fix my code when someone manages to break it. Tom Leek opened my eyes. Spotted's answer was nice too, but it's too bad that it must be done in a slightly different way to ensure compilation. It was a nice feeling when I saw my code pass in the cases mentioned by Tom Leek.
```
package library.util;
/**
* This class provides a useful interface for easy (approximate) floating
* point equality checks. This is necessary for several other classes. This
* class provides the user the power to set custom values for the
* tolerances used in comparison.
*
* @author Subhomoy Haldar (ambigram_maker)
* @version 1.5
*/
public class Numbers {
/**
* Private constructor to prevent instantiation.
*/
private Numbers() {
throw new AssertionError("No instances for you! ;P");
}
/**
* The default tolerance value for comparing the {@code float} values.
*/
public static final float DEFAULT_FLOAT_TOLERANCE = 5E-8f;
/**
* The default tolerance value for comparing the {@code double} values.
*/
public static final double DEFAULT_DOUBLE_TOLERANCE = 5E-16;
/**
* The current tolerance to be used for comparing floats.
*/
private static float floatTolerance = DEFAULT_FLOAT_TOLERANCE;
/**
* The current tolerance to be used for comparing doubles.
*/
private static double doubleTolerance =
Solution
- Please make the class final to let noone inherit the class.
- Nobody would expect a
AsserationErrorif he can inherit the class.
- Everyone who inherit the class would have duplicate javadoc.
- Please throw a
RuntimeExceptionor anIllegalStateExceptionbecause the javadoc matches better.
;Plet me miss seriousness.
- i miss
strictfpat the class definition because the math-processor may wrong.
getFloatToleranceyou dont need the getter. If it would be a bean, you need it but it is no bean.
setFloatTolerancethrows a IAE, but this behaviour is not part of the javadoc, and if you add this behaviour to the javadoc you shall write the signature of the method matching to the javadoc.assertProperLengthshould be have the correct javadoc and signature too (including the pending methods).
- The classname
Numbersshould be named "NumberHelper".
The above code runs without resulting in any assertion errors. (Yipee!!), Yipee but wait ... did you run it as JUnit-Tests or activated the-eaby manual?
- Some methods needs to have javadoc.
I have a few more but ill stop here because this class is not thread-save.
Context
StackExchange Code Review Q#104028, answer score: 8
Revisions (0)
No revisions yet.