📄 mathutils.java
字号:
} else { return Double.longBitsToDouble(sign | exponent | (mantissa + 1)); } } else { // we should decrease the mantissa if (mantissa == 0L) { return Double.longBitsToDouble(sign | (exponent - 0x0010000000000000L) | 0x000fffffffffffffL); } else { return Double.longBitsToDouble(sign | exponent | (mantissa - 1)); } } } /** * Normalize an angle in a 2&pi wide interval around a center value. * <p>This method has three main uses:</p> * <ul> * <li>normalize an angle between 0 and 2π:<br/> * <code>a = MathUtils.normalizeAngle(a, Math.PI);</code></li> * <li>normalize an angle between -π and +π<br/> * <code>a = MathUtils.normalizeAngle(a, 0.0);</code></li> * <li>compute the angle between two defining angular positions:<br> * <code>angle = MathUtils.normalizeAngle(end, start) - start;</code></li> * </ul> * <p>Note that due to numerical accuracy and since π cannot be represented * exactly, the result interval is <em>closed</em>, it cannot be half-closed * as would be more satisfactory in a purely mathematical view.</p> * @param a angle to normalize * @param center center of the desired 2π interval for the result * @return a-2kπ with integer k and center-π <= a-2kπ <= center+π * @since 1.2 */ public static double normalizeAngle(double a, double center) { return a - TWO_PI * Math.floor((a + Math.PI - center) / TWO_PI); } /** * Round the given value to the specified number of decimal places. The * value is rounded using the {@link BigDecimal#ROUND_HALF_UP} method. * * @param x the value to round. * @param scale the number of digits to the right of the decimal point. * @return the rounded value. * @since 1.1 */ public static double round(double x, int scale) { return round(x, scale, BigDecimal.ROUND_HALF_UP); } /** * Round the given value to the specified number of decimal places. The * value is rounded using the given method which is any method defined in * {@link BigDecimal}. * * @param x the value to round. * @param scale the number of digits to the right of the decimal point. * @param roundingMethod the rounding method as defined in * {@link BigDecimal}. * @return the rounded value. * @since 1.1 */ public static double round(double x, int scale, int roundingMethod) { try { return (new BigDecimal (Double.toString(x)) .setScale(scale, roundingMethod)) .doubleValue(); } catch (NumberFormatException ex) { if (Double.isInfinite(x)) { return x; } else { return Double.NaN; } } } /** * Round the given value to the specified number of decimal places. The * value is rounding using the {@link BigDecimal#ROUND_HALF_UP} method. * * @param x the value to round. * @param scale the number of digits to the right of the decimal point. * @return the rounded value. * @since 1.1 */ public static float round(float x, int scale) { return round(x, scale, BigDecimal.ROUND_HALF_UP); } /** * Round the given value to the specified number of decimal places. The * value is rounded using the given method which is any method defined in * {@link BigDecimal}. * * @param x the value to round. * @param scale the number of digits to the right of the decimal point. * @param roundingMethod the rounding method as defined in * {@link BigDecimal}. * @return the rounded value. * @since 1.1 */ public static float round(float x, int scale, int roundingMethod) { float sign = indicator(x); float factor = (float)Math.pow(10.0f, scale) * sign; return (float)roundUnscaled(x * factor, sign, roundingMethod) / factor; } /** * Round the given non-negative, value to the "nearest" integer. Nearest is * determined by the rounding method specified. Rounding methods are defined * in {@link BigDecimal}. * * @param unscaled the value to round. * @param sign the sign of the original, scaled value. * @param roundingMethod the rounding method as defined in * {@link BigDecimal}. * @return the rounded value. * @since 1.1 */ private static double roundUnscaled(double unscaled, double sign, int roundingMethod) { switch (roundingMethod) { case BigDecimal.ROUND_CEILING : if (sign == -1) { unscaled = Math.floor(nextAfter(unscaled, Double.NEGATIVE_INFINITY)); } else { unscaled = Math.ceil(nextAfter(unscaled, Double.POSITIVE_INFINITY)); } break; case BigDecimal.ROUND_DOWN : unscaled = Math.floor(nextAfter(unscaled, Double.NEGATIVE_INFINITY)); break; case BigDecimal.ROUND_FLOOR : if (sign == -1) { unscaled = Math.ceil(nextAfter(unscaled, Double.POSITIVE_INFINITY)); } else { unscaled = Math.floor(nextAfter(unscaled, Double.NEGATIVE_INFINITY)); } break; case BigDecimal.ROUND_HALF_DOWN : { unscaled = nextAfter(unscaled, Double.NEGATIVE_INFINITY); double fraction = unscaled - Math.floor(unscaled); if (fraction > 0.5) { unscaled = Math.ceil(unscaled); } else { unscaled = Math.floor(unscaled); } break; } case BigDecimal.ROUND_HALF_EVEN : { double fraction = unscaled - Math.floor(unscaled); if (fraction > 0.5) { unscaled = Math.ceil(unscaled); } else if (fraction < 0.5) { unscaled = Math.floor(unscaled); } else { // The following equality test is intentional and needed for rounding purposes if (Math.floor(unscaled) / 2.0 == Math.floor(Math .floor(unscaled) / 2.0)) { // even unscaled = Math.floor(unscaled); } else { // odd unscaled = Math.ceil(unscaled); } } break; } case BigDecimal.ROUND_HALF_UP : { unscaled = nextAfter(unscaled, Double.POSITIVE_INFINITY); double fraction = unscaled - Math.floor(unscaled); if (fraction >= 0.5) { unscaled = Math.ceil(unscaled); } else { unscaled = Math.floor(unscaled); } break; } case BigDecimal.ROUND_UNNECESSARY : if (unscaled != Math.floor(unscaled)) { throw new ArithmeticException("Inexact result from rounding"); } break; case BigDecimal.ROUND_UP : unscaled = Math.ceil(nextAfter(unscaled, Double.POSITIVE_INFINITY)); break; default : throw new IllegalArgumentException("Invalid rounding method."); } return unscaled; } /** * Returns the <a href="http://mathworld.wolfram.com/Sign.html"> sign</a> * for byte value <code>x</code>. * <p> * For a byte value x, this method returns (byte)(+1) if x > 0, (byte)(0) if * x = 0, and (byte)(-1) if x < 0.</p> * * @param x the value, a byte * @return (byte)(+1), (byte)(0), or (byte)(-1), depending on the sign of x */ public static byte sign(final byte x) { return (x == ZB) ? ZB : (x > ZB) ? PB : NB; } /** * Returns the <a href="http://mathworld.wolfram.com/Sign.html"> sign</a> * for double precision <code>x</code>. * <p> * For a double value <code>x</code>, this method returns * <code>+1.0</code> if <code>x > 0</code>, <code>0.0</code> if * <code>x = 0.0</code>, and <code>-1.0</code> if <code>x < 0</code>. * Returns <code>NaN</code> if <code>x</code> is <code>NaN</code>.</p> * * @param x the value, a double * @return +1.0, 0.0, or -1.0, depending on the sign of x */ public static double sign(final double x) { if (Double.isNaN(x)) { return Double.NaN; } return (x == 0.0) ? 0.0 : (x > 0.0) ? 1.0 : -1.0; } /** * Returns the <a href="http://mathworld.wolfram.com/Sign.html"> sign</a> * for float value <code>x</code>. * <p> * For a float value x, this method returns +1.0F if x > 0, 0.0F if x = * 0.0F, and -1.0F if x < 0. Returns <code>NaN</code> if <code>x</code> * is <code>NaN</code>.</p> * * @param x the value, a float * @return +1.0F, 0.0F, or -1.0F, depending on the sign of x */ public static float sign(final float x) { if (Float.isNaN(x)) { return Float.NaN; } return (x == 0.0F) ? 0.0F : (x > 0.0F) ? 1.0F : -1.0F; } /** * Returns the <a href="http://mathworld.wolfram.com/Sign.html"> sign</a> * for int value <code>x</code>. * <p> * For an int value x, this method returns +1 if x > 0, 0 if x = 0, and -1 * if x < 0.</p> * * @param x the value, an int * @return +1, 0, or -1, depending on the sign of x */ public static int sign(final int x) { return (x == 0) ? 0 : (x > 0) ? 1 : -1; } /** * Returns the <a href="http://mathworld.wolfram.com/Sign.html"> sign</a> * for long value <code>x</code>. * <p> * For a long value x, this method returns +1L if x > 0, 0L if x = 0, and * -1L if x < 0.</p> * * @param x the value, a long * @return +1L, 0L, or -1L, depending on the sign of x */ public static long sign(final long x) { return (x == 0L) ? 0L : (x > 0L) ? 1L : -1L; } /** * Returns the <a href="http://mathworld.wolfram.com/Sign.html"> sign</a> * for short value <code>x</code>. * <p> * For a short value x, this method returns (short)(+1) if x > 0, (short)(0) * if x = 0, and (short)(-1) if x < 0.</p> * * @param x the value, a short * @return (short)(+1), (short)(0), or (short)(-1), depending on the sign of * x */ public static short sign(final short x) { return (x == ZS) ? ZS : (x > ZS) ? PS : NS; } /** * Returns the <a href="http://mathworld.wolfram.com/HyperbolicSine.html"> * hyperbolic sine</a> of x. * * @param x double value for which to find the hyperbolic sine * @return hyperbolic sine of x */ public static double sinh(double x) { return (Math.exp(x) - Math.exp(-x)) / 2.0; } /** * Subtract two integers, checking for overflow. * * @param x the minuend * @param y the subtrahend * @return the difference <code>x-y</code> * @throws ArithmeticException if the result can not be represented as an * int * @since 1.1 */ public static int subAndCheck(int x, int y) { long s = (long)x - (long)y; if (s < Integer.MIN_VALUE || s > Integer.MAX_VALUE) { throw new ArithmeticException("overflow: subtract"); } return (int)s; } /** * Subtract two long integers, checking for overflow. * * @param a first value * @param b second value * @return the difference <code>a-b</code> * @throws ArithmeticException if the result can not be represented as an * long * @since 1.2 */ public static long subAndCheck(long a, long b) { long ret; String msg = "overflow: subtract"; if (b == Long.MIN_VALUE) { if (a < 0) { ret = a - b; } else { throw new ArithmeticException(msg); } } else { // use additive inverse ret = addAndCheck(a, -b, msg); } return ret; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -