/** * Finds the greatest float less than <var>f</var>. * If {@code NaN}, returns same value. * * @todo Remove this method when we will be allowed to use J2SE 1.5. */ public static float previous(final float f) { return next(f, false); }
/** * Finds the least float greater than <var>f</var>. * If {@code NaN}, returns same value. * * @todo Remove this method when we will be allowed to use J2SE 1.5. */ public static float next(final float f) { return next(f, true); }
/** * Round the specified value, providing that the difference between the original value and * the rounded value is not greater than the specified amount of floating point units. This * method can be used for hiding floating point error likes 2.9999999996. * * @param value The value to round. * @param flu The amount of floating point units. * @return The rounded value, of {@code value} if it was not close enough to an integer. */ public static double round(final double value, int flu) { final double target = Math.rint(value); if (value != target) { final boolean pos = (value < target); double candidate = value; while (--flu >= 0) { candidate = pos ? next(candidate) : previous(candidate); if (candidate == target) { return target; } } } return value; }
/** * Try to remove at least {@code n} fraction digits in the string representation of * the specified value. This method try small changes to {@code value}, by adding or * substracting a maximum of 4 ulps. If there is no small change that remove at least * {@code n} fraction digits, then the value is returned unchanged. This method is * used for hiding rounding errors, like in conversions from radians to degrees. * * <P>Example: {@code XMath.fixRoundingError(-61.500000000000014, 12)} returns * {@code -61.5}. * * @param value The value to fix. * @param n The minimum amount of fraction digits. * @return The fixed value, or the unchanged {@code value} if there is no small change * that remove at least {@code n} fraction digits. */ public static double fixRoundingError(final double value, int n) { double lower = value; double upper = value; n = countFractionDigits(value) - n; if (n > 0) { for (int i=0; i<4; i++) { if (countFractionDigits(lower = previous(lower)) <= n) return lower; if (countFractionDigits(upper = next (upper)) <= n) return upper; } } return value; }