/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package java.lang; import java.util.Random; /** * Class Math provides basic math constants and operations such as trigonometric * functions, hyperbolic functions, exponential, logarithms, etc. */ public final class Math { /** * The double value closest to e, the base of the natural logarithm. */ public static final double E = 2.718281828459045; /** * The double value closest to pi, the ratio of a circle's circumference to * its diameter. */ public static final double PI = 3.141592653589793; private static Random random; /** * Prevents this class from being instantiated. */ private Math() { } /** * Returns the absolute value of the argument. *

* Special cases: *

*/ public static native double abs(double d); /** * Returns the absolute value of the argument. *

* Special cases: *

*/ public static native float abs(float f); /** * Returns the absolute value of the argument. *

* If the argument is {@code Integer.MIN_VALUE}, {@code Integer.MIN_VALUE} * is returned. */ public static native int abs(int i); /** * Returns the absolute value of the argument. If the argument is {@code * Long.MIN_VALUE}, {@code Long.MIN_VALUE} is returned. */ public static native long abs(long l); /** * Returns the closest double approximation of the arc cosine of the * argument within the range {@code [0..pi]}. The returned result is within * 1 ulp (unit in the last place) of the real result. *

* Special cases: *

* * @param d * the value to compute arc cosine of. * @return the arc cosine of the argument. */ public static native double acos(double d); /** * Returns the closest double approximation of the arc sine of the argument * within the range {@code [-pi/2..pi/2]}. The returned result is within 1 * ulp (unit in the last place) of the real result. *

* Special cases: *

* * @param d * the value whose arc sine has to be computed. * @return the arc sine of the argument. */ public static native double asin(double d); /** * Returns the closest double approximation of the arc tangent of the * argument within the range {@code [-pi/2..pi/2]}. The returned result is * within 1 ulp (unit in the last place) of the real result. *

* Special cases: *

* * @param d * the value whose arc tangent has to be computed. * @return the arc tangent of the argument. */ public static native double atan(double d); /** * Returns the closest double approximation of the arc tangent of {@code * y/x} within the range {@code [-pi..pi]}. This is the angle of the polar * representation of the rectangular coordinates (x,y). The returned result * is within 2 ulps (units in the last place) of the real result. *

* Special cases: *

* * @param y * the numerator of the value whose atan has to be computed. * @param x * the denominator of the value whose atan has to be computed. * @return the arc tangent of {@code y/x}. */ public static native double atan2(double y, double x); /** * Returns the closest double approximation of the cube root of the * argument. *

* Special cases: *

* * @param d * the value whose cube root has to be computed. * @return the cube root of the argument. */ public static native double cbrt(double d); /** * Returns the double conversion of the most negative (closest to negative * infinity) integer value greater than or equal to the argument. *

* Special cases: *

*/ public static native double ceil(double d); /** * Returns the closest double approximation of the cosine of the argument. * The returned result is within 1 ulp (unit in the last place) of the real * result. *

* Special cases: *

* * @param d * the angle whose cosine has to be computed, in radians. * @return the cosine of the argument. */ public static native double cos(double d); /** * Returns the closest double approximation of the hyperbolic cosine of the * argument. The returned result is within 2.5 ulps (units in the last * place) of the real result. *

* Special cases: *

* * @param d * the value whose hyperbolic cosine has to be computed. * @return the hyperbolic cosine of the argument. */ public static native double cosh(double d); /** * Returns the closest double approximation of the raising "e" to the power * of the argument. The returned result is within 1 ulp (unit in the last * place) of the real result. *

* Special cases: *

* * @param d * the value whose exponential has to be computed. * @return the exponential of the argument. */ public static native double exp(double d); /** * Returns the closest double approximation of {@code e} {@code * d}{@code - 1}. If the argument is very close to 0, it is much more * accurate to use {@code expm1(d)+1} than {@code exp(d)} (due to * cancellation of significant digits). The returned result is within 1 ulp * (unit in the last place) of the real result. *

* For any finite input, the result is not less than -1.0. If the real * result is within 0.5 ulp of -1, -1.0 is returned. *

* Special cases: *

* * @param d * the value to compute the {@code e}{@code d} * {@code - 1} of. * @return the {@code e}{@code d}{@code - 1} value of the * argument. */ public static native double expm1(double d); /** * Returns the double conversion of the most positive (closest to positive * infinity) integer value less than or equal to the argument. *

* Special cases: *

*/ public static native double floor(double d); /** * Returns {@code sqrt(}{@code x}{@code 2}{@code +} * {@code y}{@code 2}{@code )}. The final result is without * medium underflow or overflow. The returned result is within 1 ulp (unit * in the last place) of the real result. If one parameter remains constant, * the result should be semi-monotonic. *

* Special cases: *

* * @param x * a double number. * @param y * a double number. * @return the {@code sqrt(}{@code x}{@code 2}{@code +} * {@code y}{@code 2}{@code )} value of the * arguments. */ public static native double hypot(double x, double y); /** * Returns the remainder of dividing {@code x} by {@code y} using the IEEE * 754 rules. The result is {@code x-round(x/p)*p} where {@code round(x/p)} * is the nearest integer (rounded to even), but without numerical * cancellation problems. *

* Special cases: *

* * @param x * the numerator of the operation. * @param y * the denominator of the operation. * @return the IEEE754 floating point reminder of of {@code x/y}. */ public static native double IEEEremainder(double x, double y); /** * Returns the closest double approximation of the natural logarithm of the * argument. The returned result is within 1 ulp (unit in the last place) of * the real result. *

* Special cases: *

* * @param d * the value whose log has to be computed. * @return the natural logarithm of the argument. */ public static native double log(double d); /** * Returns the closest double approximation of the base 10 logarithm of the * argument. The returned result is within 1 ulp (unit in the last place) of * the real result. *

* Special cases: *

* * @param d * the value whose base 10 log has to be computed. * @return the natural logarithm of the argument. */ public static native double log10(double d); /** * Returns the closest double approximation of the natural logarithm of the * sum of the argument and 1. If the argument is very close to 0, it is much * more accurate to use {@code log1p(d)} than {@code log(1.0+d)} (due to * numerical cancellation). The returned result is within 1 ulp (unit in the * last place) of the real result and is semi-monotonic. *

* Special cases: *

* * @param d * the value to compute the {@code ln(1+d)} of. * @return the natural logarithm of the sum of the argument and 1. */ public static native double log1p(double d); /** * Returns the most positive (closest to positive infinity) of the two * arguments. *

* Special cases: *

*/ public static double max(double d1, double d2) { if (d1 > d2) { return d1; } if (d1 < d2) { return d2; } /* if either arg is NaN, return NaN */ if (d1 != d2) { return Double.NaN; } /* max(+0.0,-0.0) == +0.0 */ /* Double.doubleToRawLongBits(0.0d) == 0 */ if (Double.doubleToRawLongBits(d1) != 0) { return d2; } return 0.0d; } /** * Returns the most positive (closest to positive infinity) of the two * arguments. *

* Special cases: *

*/ public static float max(float f1, float f2) { if (f1 > f2) { return f1; } if (f1 < f2) { return f2; } /* if either arg is NaN, return NaN */ if (f1 != f2) { return Float.NaN; } /* max(+0.0,-0.0) == +0.0 */ /* Float.floatToRawIntBits(0.0f) == 0*/ if (Float.floatToRawIntBits(f1) != 0) { return f2; } return 0.0f; } /** * Returns the most positive (closest to positive infinity) of the two * arguments. */ public static native int max(int i1, int i2); /** * Returns the most positive (closest to positive infinity) of the two * arguments. */ public static long max(long l1, long l2) { return l1 > l2 ? l1 : l2; } /** * Returns the most negative (closest to negative infinity) of the two * arguments. *

* Special cases: *

*/ public static double min(double d1, double d2) { if (d1 > d2) { return d2; } if (d1 < d2) { return d1; } /* if either arg is NaN, return NaN */ if (d1 != d2) { return Double.NaN; } /* min(+0.0,-0.0) == -0.0 */ /* 0x8000000000000000L == Double.doubleToRawLongBits(-0.0d) */ if (Double.doubleToRawLongBits(d1) == 0x8000000000000000L) { return -0.0d; } return d2; } /** * Returns the most negative (closest to negative infinity) of the two * arguments. *

* Special cases: *

*/ public static float min(float f1, float f2) { if (f1 > f2) { return f2; } if (f1 < f2) { return f1; } /* if either arg is NaN, return NaN */ if (f1 != f2) { return Float.NaN; } /* min(+0.0,-0.0) == -0.0 */ /* 0x80000000 == Float.floatToRawIntBits(-0.0f) */ if (Float.floatToRawIntBits(f1) == 0x80000000) { return -0.0f; } return f2; } /** * Returns the most negative (closest to negative infinity) of the two * arguments. */ public static native int min(int i1, int i2); /** * Returns the most negative (closest to negative infinity) of the two * arguments. */ public static long min(long l1, long l2) { return l1 < l2 ? l1 : l2; } /** * Returns the closest double approximation of the result of raising {@code * x} to the power of {@code y}. *

* Special cases: *

* * @param x * the base of the operation. * @param y * the exponent of the operation. * @return {@code x} to the power of {@code y}. */ public static native double pow(double x, double y); /** * Returns the double conversion of the result of rounding the argument to * an integer. Tie breaks are rounded towards even. *

* Special cases: *

* * @param d * the value to be rounded. * @return the closest integer to the argument (as a double). */ public static native double rint(double d); /** * Returns the result of rounding the argument to an integer. The result is * equivalent to {@code (long) Math.floor(d+0.5)}. *

* Special cases: *

* * @param d * the value to be rounded. * @return the closest integer to the argument. */ public static long round(double d) { // check for NaN if (d != d) { return 0L; } return (long) floor(d + 0.5d); } /** * Returns the result of rounding the argument to an integer. The result is * equivalent to {@code (int) Math.floor(f+0.5)}. *

* Special cases: *

* * @param f * the value to be rounded. * @return the closest integer to the argument. */ public static int round(float f) { // check for NaN if (f != f) { return 0; } return (int) floor(f + 0.5f); } /** * Returns the signum function of the argument. If the argument is less than * zero, it returns -1.0. If the argument is greater than zero, 1.0 is * returned. If the argument is either positive or negative zero, the * argument is returned as result. *

* Special cases: *

* * @param d * the value whose signum has to be computed. * @return the value of the signum function. */ public static double signum(double d) { if (Double.isNaN(d)) { return Double.NaN; } double sig = d; if (d > 0) { sig = 1.0; } else if (d < 0) { sig = -1.0; } return sig; } /** * Returns the signum function of the argument. If the argument is less than * zero, it returns -1.0. If the argument is greater than zero, 1.0 is * returned. If the argument is either positive or negative zero, the * argument is returned as result. *

* Special cases: *

* * @param f * the value whose signum has to be computed. * @return the value of the signum function. */ public static float signum(float f) { if (Float.isNaN(f)) { return Float.NaN; } float sig = f; if (f > 0) { sig = 1.0f; } else if (f < 0) { sig = -1.0f; } return sig; } /** * Returns the closest double approximation of the sine of the argument. The * returned result is within 1 ulp (unit in the last place) of the real * result. *

* Special cases: *

* * @param d * the angle whose sin has to be computed, in radians. * @return the sine of the argument. */ public static native double sin(double d); /** * Returns the closest double approximation of the hyperbolic sine of the * argument. The returned result is within 2.5 ulps (units in the last * place) of the real result. *

* Special cases: *

* * @param d * the value whose hyperbolic sine has to be computed. * @return the hyperbolic sine of the argument. */ public static native double sinh(double d); /** * Returns the closest double approximation of the square root of the * argument. *

* Special cases: *

*/ public static native double sqrt(double d); /** * Returns the closest double approximation of the tangent of the argument. * The returned result is within 1 ulp (unit in the last place) of the real * result. *

* Special cases: *

* * @param d * the angle whose tangent has to be computed, in radians. * @return the tangent of the argument. */ public static native double tan(double d); /** * Returns the closest double approximation of the hyperbolic tangent of the * argument. The absolute value is always less than 1. The returned result * is within 2.5 ulps (units in the last place) of the real result. If the * real result is within 0.5ulp of 1 or -1, it should return exactly +1 or * -1. *

* Special cases: *

* * @param d * the value whose hyperbolic tangent has to be computed. * @return the hyperbolic tangent of the argument. */ public static native double tanh(double d); /** * Returns a pseudo-random double {@code n}, where {@code n >= 0.0 && n < 1.0}. * This method reuses a single instance of {@link java.util.Random}. * This method is thread-safe because access to the {@code Random} is synchronized, * but this harms scalability. Applications may find a performance benefit from * allocating a {@code Random} for each of their threads. * * @return a pseudo-random number. */ public static synchronized double random() { if (random == null) { random = new Random(); } return random.nextDouble(); } /** * Returns the measure in radians of the supplied degree angle. The result * is {@code angdeg / 180 * pi}. *

* Special cases: *

* * @param angdeg * an angle in degrees. * @return the radian measure of the angle. */ public static double toRadians(double angdeg) { return angdeg / 180d * PI; } /** * Returns the measure in degrees of the supplied radian angle. The result * is {@code angrad * 180 / pi}. *

* Special cases: *

* * @param angrad * an angle in radians. * @return the degree measure of the angle. */ public static double toDegrees(double angrad) { return angrad * 180d / PI; } /** * Returns the argument's ulp (unit in the last place). The size of a ulp of * a double value is the positive distance between this value and the double * value next larger in magnitude. For non-NaN {@code x}, {@code ulp(-x) == * ulp(x)}. *

* Special cases: *

* * @param d * the floating-point value to compute ulp of. * @return the size of a ulp of the argument. */ public static double ulp(double d) { // special cases if (Double.isInfinite(d)) { return Double.POSITIVE_INFINITY; } else if (d == Double.MAX_VALUE || d == -Double.MAX_VALUE) { return pow(2, 971); } d = abs(d); return nextafter(d, Double.MAX_VALUE) - d; } private static native double nextafter(double x, double y); /** * Returns the argument's ulp (unit in the last place). The size of a ulp of * a float value is the positive distance between this value and the float * value next larger in magnitude. For non-NaN {@code x}, {@code ulp(-x) == * ulp(x)}. *

* Special cases: *

* * @param f * the floating-point value to compute ulp of. * @return the size of a ulp of the argument. */ public static float ulp(float f) { // special cases if (Float.isNaN(f)) { return Float.NaN; } else if (Float.isInfinite(f)) { return Float.POSITIVE_INFINITY; } else if (f == Float.MAX_VALUE || f == -Float.MAX_VALUE) { return (float) pow(2, 104); } f = Math.abs(f); int hx = Float.floatToRawIntBits(f); int hy = Float.floatToRawIntBits(Float.MAX_VALUE); if ((hx & 0x7fffffff) == 0) { /* f == 0 */ return Float.intBitsToFloat((hy & 0x80000000) | 0x1); } if ((hx > 0) ^ (hx > hy)) { /* |f| < |Float.MAX_VALUE| */ hx += 1; } else { hx -= 1; } return Float.intBitsToFloat(hx) - f; } /** * Returns a double with the given magnitude and the sign of {@code sign}. * If {@code sign} is NaN, the sign of the result is arbitrary. * If you need a determinate sign in such cases, use {@code StrictMath.copySign}. * @since 1.6 */ public static double copySign(double magnitude, double sign) { long magnitudeBits = Double.doubleToRawLongBits(magnitude); long signBits = Double.doubleToRawLongBits(sign); magnitudeBits = (magnitudeBits & ~Double.SIGN_MASK) | (signBits & Double.SIGN_MASK); return Double.longBitsToDouble(magnitudeBits); } /** * Returns a float with the given magnitude and the sign of {@code sign}. * If {@code sign} is NaN, the sign of the result is arbitrary. * If you need a determinate sign in such cases, use {@code StrictMath.copySign}. * @since 1.6 */ public static float copySign(float magnitude, float sign) { int magnitudeBits = Float.floatToRawIntBits(magnitude); int signBits = Float.floatToRawIntBits(sign); magnitudeBits = (magnitudeBits & ~Float.SIGN_MASK) | (signBits & Float.SIGN_MASK); return Float.intBitsToFloat(magnitudeBits); } /** * Returns the unbiased base-2 exponent of float {@code f}. * @since 1.6 */ public static int getExponent(float f) { int bits = Float.floatToRawIntBits(f); bits = (bits & Float.EXPONENT_MASK) >> Float.MANTISSA_BITS; return bits - Float.EXPONENT_BIAS; } /** * Returns the unbiased base-2 exponent of double {@code d}. * @since 1.6 */ public static int getExponent(double d) { long bits = Double.doubleToRawLongBits(d); bits = (bits & Double.EXPONENT_MASK) >> Double.MANTISSA_BITS; return (int) bits - Double.EXPONENT_BIAS; } /** * Returns the next double after {@code start} in the given {@code direction}. * @since 1.6 */ public static double nextAfter(double start, double direction) { if (start == 0 && direction == 0) { return direction; } return nextafter(start, direction); } /** * Returns the next float after {@code start} in the given {@code direction}. * @since 1.6 */ public static float nextAfter(float start, double direction) { if (Float.isNaN(start) || Double.isNaN(direction)) { return Float.NaN; } if (start == 0 && direction == 0) { return (float) direction; } if ((start == Float.MIN_VALUE && direction < start) || (start == -Float.MIN_VALUE && direction > start)) { return (start > 0 ? 0f : -0f); } if (Float.isInfinite(start) && (direction != start)) { return (start > 0 ? Float.MAX_VALUE : -Float.MAX_VALUE); } if ((start == Float.MAX_VALUE && direction > start) || (start == -Float.MAX_VALUE && direction < start)) { return (start > 0 ? Float.POSITIVE_INFINITY : Float.NEGATIVE_INFINITY); } if (direction > start) { if (start > 0) { return Float.intBitsToFloat(Float.floatToIntBits(start) + 1); } if (start < 0) { return Float.intBitsToFloat(Float.floatToIntBits(start) - 1); } return +Float.MIN_VALUE; } if (direction < start) { if (start > 0) { return Float.intBitsToFloat(Float.floatToIntBits(start) - 1); } if (start < 0) { return Float.intBitsToFloat(Float.floatToIntBits(start) + 1); } return -Float.MIN_VALUE; } return (float) direction; } /** * Returns the next double larger than {@code d}. * @since 1.6 */ public static double nextUp(double d) { if (Double.isNaN(d)) { return Double.NaN; } if (d == Double.POSITIVE_INFINITY) { return Double.POSITIVE_INFINITY; } if (d == 0) { return Double.MIN_VALUE; } else if (d > 0) { return Double.longBitsToDouble(Double.doubleToLongBits(d) + 1); } else { return Double.longBitsToDouble(Double.doubleToLongBits(d) - 1); } } /** * Returns the next float larger than {@code f}. * @since 1.6 */ public static float nextUp(float f) { if (Float.isNaN(f)) { return Float.NaN; } if (f == Float.POSITIVE_INFINITY) { return Float.POSITIVE_INFINITY; } if (f == 0) { return Float.MIN_VALUE; } else if (f > 0) { return Float.intBitsToFloat(Float.floatToIntBits(f) + 1); } else { return Float.intBitsToFloat(Float.floatToIntBits(f) - 1); } } /** * Returns {@code d} * 2^{@code scaleFactor}. The result may be rounded. * @since 1.6 */ public static double scalb(double d, int scaleFactor) { if (Double.isNaN(d) || Double.isInfinite(d) || d == 0) { return d; } // change double to long for calculation long bits = Double.doubleToLongBits(d); // the sign of the results must be the same of given d long sign = bits & Double.SIGN_MASK; // calculates the factor of the result long factor = ((bits & Double.EXPONENT_MASK) >> Double.MANTISSA_BITS) - Double.EXPONENT_BIAS + scaleFactor; // calculates the factor of sub-normal values int subNormalFactor = Long.numberOfLeadingZeros(bits & ~Double.SIGN_MASK) - Double.NON_MANTISSA_BITS; if (subNormalFactor < 0) { // not sub-normal values subNormalFactor = 0; } else { factor = factor - subNormalFactor; } if (factor > Double.MAX_EXPONENT) { return (d > 0 ? Double.POSITIVE_INFINITY : Double.NEGATIVE_INFINITY); } long result; // if result is a sub-normal if (factor <= -Double.EXPONENT_BIAS) { // the number of digits that shifts long digits = factor + Double.EXPONENT_BIAS + subNormalFactor; if (Math.abs(d) < Double.MIN_NORMAL) { // origin d is already sub-normal result = shiftLongBits(bits & Double.MANTISSA_MASK, digits); } else { // origin d is not sub-normal, change mantissa to sub-normal result = shiftLongBits(bits & Double.MANTISSA_MASK | 0x0010000000000000L, digits - 1); } } else { if (Math.abs(d) >= Double.MIN_NORMAL) { // common situation result = ((factor + Double.EXPONENT_BIAS) << Double.MANTISSA_BITS) | (bits & Double.MANTISSA_MASK); } else { // origin d is sub-normal, change mantissa to normal style result = ((factor + Double.EXPONENT_BIAS) << Double.MANTISSA_BITS) | ((bits << (subNormalFactor + 1)) & Double.MANTISSA_MASK); } } return Double.longBitsToDouble(result | sign); } /** * Returns {@code d} * 2^{@code scaleFactor}. The result may be rounded. * @since 1.6 */ public static float scalb(float d, int scaleFactor) { if (Float.isNaN(d) || Float.isInfinite(d) || d == 0) { return d; } int bits = Float.floatToIntBits(d); int sign = bits & Float.SIGN_MASK; int factor = ((bits & Float.EXPONENT_MASK) >> Float.MANTISSA_BITS) - Float.EXPONENT_BIAS + scaleFactor; // calculates the factor of sub-normal values int subNormalFactor = Integer.numberOfLeadingZeros(bits & ~Float.SIGN_MASK) - Float.NON_MANTISSA_BITS; if (subNormalFactor < 0) { // not sub-normal values subNormalFactor = 0; } else { factor = factor - subNormalFactor; } if (factor > Float.MAX_EXPONENT) { return (d > 0 ? Float.POSITIVE_INFINITY : Float.NEGATIVE_INFINITY); } int result; // if result is a sub-normal if (factor <= -Float.EXPONENT_BIAS) { // the number of digits that shifts int digits = factor + Float.EXPONENT_BIAS + subNormalFactor; if (Math.abs(d) < Float.MIN_NORMAL) { // origin d is already sub-normal result = shiftIntBits(bits & Float.MANTISSA_MASK, digits); } else { // origin d is not sub-normal, change mantissa to sub-normal result = shiftIntBits(bits & Float.MANTISSA_MASK | 0x00800000, digits - 1); } } else { if (Math.abs(d) >= Float.MIN_NORMAL) { // common situation result = ((factor + Float.EXPONENT_BIAS) << Float.MANTISSA_BITS) | (bits & Float.MANTISSA_MASK); } else { // origin d is sub-normal, change mantissa to normal style result = ((factor + Float.EXPONENT_BIAS) << Float.MANTISSA_BITS) | ((bits << (subNormalFactor + 1)) & Float.MANTISSA_MASK); } } return Float.intBitsToFloat(result | sign); } // Shifts integer bits as float, if the digits is positive, left-shift; if // not, shift to right and calculate its carry. private static int shiftIntBits(int bits, int digits) { if (digits > 0) { return bits << digits; } // change it to positive int absDigits = -digits; if (!(Integer.numberOfLeadingZeros(bits & ~Float.SIGN_MASK) <= (32 - absDigits))) { return 0; } int ret = bits >> absDigits; boolean halfBit = ((bits >> (absDigits - 1)) & 0x1) == 1; if (halfBit) { if (Integer.numberOfTrailingZeros(bits) < (absDigits - 1)) { ret = ret + 1; } if (Integer.numberOfTrailingZeros(bits) == (absDigits - 1)) { if ((ret & 0x1) == 1) { ret = ret + 1; } } } return ret; } // Shifts long bits as double, if the digits is positive, left-shift; if // not, shift to right and calculate its carry. private static long shiftLongBits(long bits, long digits) { if (digits > 0) { return bits << digits; } // change it to positive long absDigits = -digits; if (!(Long.numberOfLeadingZeros(bits & ~Double.SIGN_MASK) <= (64 - absDigits))) { return 0; } long ret = bits >> absDigits; boolean halfBit = ((bits >> (absDigits - 1)) & 0x1) == 1; if (halfBit) { // some bits will remain after shifting, calculates its carry // subnormal if (Long.numberOfTrailingZeros(bits) < (absDigits - 1)) { ret = ret + 1; } if (Long.numberOfTrailingZeros(bits) == (absDigits - 1)) { if ((ret & 0x1) == 1) { ret = ret + 1; } } } return ret; } }