1215 lines · 48.3 KB · Java
RawDownload
     * one floating-point add or multiply as opposed to, say, four     * cycles for normal operands.  For processors with very slow     * subnormal execution, scalb would be fastest if written entirely     * with integer operations; in other words, scalb would need to     * include the logic of performing correct rounding of subnormal     * values.  This could be reasonably done in at most a few hundred     * cycles.  However, this approach may penalize normal operations     * since at least the exponent of the floating-point argument must     * be examined.     *     * The approach taken in this implementation is a compromise.     * Floating-point multiplication is used to do most of the work;     * but knowingly multiplying by a subnormal scaling factor is     * avoided.  However, the floating-point argument is not examined     * to see whether or not it is subnormal since subnormal inputs     * are assumed to be rare.  At most three multiplies are needed to     * scale from the largest to smallest exponent ranges (scaling     * down, at most two multiplies are needed if subnormal scaling     * factors are allowed).  However, in this implementation an     * expensive integer remainder operation is avoided at the cost of     * requiring five floating-point multiplies in the worst case,     * which should still be a performance win.     *     * If scaling of entire arrays is a concern, it would probably be     * more efficient to provide a double[] scalb(double[], int)     * version of scalb to avoid having to recompute the needed     * scaling factors for each floating-point value.     */     /**     * Return {@code d} &times;     * 2<sup>{@code scale_factor}</sup> rounded as if performed     * by a single correctly rounded floating-point multiply to a     * member of the double value set.  See section 4.2.3 of     * <cite>The Java&trade; Language Specification</cite>     * for a discussion of floating-point     * value sets.  If the exponent of the result is between the     * {@code double}'s minimum exponent and maximum exponent,     * the answer is calculated exactly.  If the exponent of the     * result would be larger than {@code doubles}'s maximum     * exponent, an infinity is returned.  Note that if the result is     * subnormal, precision may be lost; that is, when {@code scalb(x,     * n)} is subnormal, {@code scalb(scalb(x, n), -n)} may     * not equal <i>x</i>.  When the result is non-NaN, the result has     * the same sign as {@code d}.     *     *<p>     * Special cases:     * <ul>     * <li> If the first argument is NaN, NaN is returned.     * <li> If the first argument is infinite, then an infinity of the     * same sign is returned.     * <li> If the first argument is zero, then a zero of the same     * sign is returned.     * </ul>     *     * @param d number to be scaled by a power of two.     * @param scale_factor power of 2 used to scale {@code d}     * @return {@code d * }2<sup>{@code scale_factor}</sup>     * @author Joseph D. Darcy     */    public static double scalb(double d, int scale_factor) {        /*         * This method does not need to be declared strictfp to         * compute the same correct result on all platforms.  When         * scaling up, it does not matter what order the         * multiply-store operations are done; the result will be         * finite or overflow regardless of the operation ordering.         * However, to get the correct result when scaling down, a         * particular ordering must be used.         *         * When scaling down, the multiply-store operations are         * sequenced so that it is not possible for two consecutive         * multiply-stores to return subnormal results.  If one         * multiply-store result is subnormal, the next multiply will         * round it away to zero.  This is done by first multiplying         * by 2 ^ (scale_factor % n) and then multiplying several         * times by by 2^n as needed where n is the exponent of number         * that is a covenient power of two.  In this way, at most one         * real rounding error occurs.  If the double value set is         * being used exclusively, the rounding will occur on a         * multiply.  If the double-extended-exponent value set is         * being used, the products will (perhaps) be exact but the         * stores to d are guaranteed to round to the double value         * set.         *         * It is _not_ a valid implementation to first multiply d by         * 2^MIN_EXPONENT and then by 2 ^ (scale_factor %         * MIN_EXPONENT) since even in a strictfp program double         * rounding on underflow could occur; e.g. if the scale_factor         * argument was (MIN_EXPONENT - n) and the exponent of d was a         * little less than -(MIN_EXPONENT - n), meaning the final         * result would be subnormal.         *         * Since exact reproducibility of this method can be achieved         * without any undue performance burden, there is no         * compelling reason to allow double rounding on underflow in         * scalb.         */         // magnitude of a power of two so large that scaling a finite        // nonzero value by it would be guaranteed to over or        // underflow; due to rounding, scaling down takes takes an        // additional power of two which is reflected here        final int MAX_SCALE = DoubleConsts.MAX_EXPONENT + -DoubleConsts.MIN_EXPONENT +                              DoubleConsts.SIGNIFICAND_WIDTH + 1;        int exp_adjust = 0;        int scale_increment = 0;        double exp_delta = Double.NaN;         // Make sure scaling factor is in a reasonable range         if(scale_factor < 0) {            scale_factor = Math.max(scale_factor, -MAX_SCALE);            scale_increment = -512;            exp_delta = twoToTheDoubleScaleDown;        }        else {            scale_factor = Math.min(scale_factor, MAX_SCALE);            scale_increment = 512;            exp_delta = twoToTheDoubleScaleUp;        }         // Calculate (scale_factor % +/-512), 512 = 2^9, using        // technique from "Hacker's Delight" section 10-2.        int t = (scale_factor >> 9-1) >>> 32 - 9;        exp_adjust = ((scale_factor + t) & (512 -1)) - t;         d *= powerOfTwoD(exp_adjust);        scale_factor -= exp_adjust;         while(scale_factor != 0) {            d *= exp_delta;            scale_factor -= scale_increment;        }        return d;    }     /**     * Return {@code f} &times;     * 2<sup>{@code scale_factor}</sup> rounded as if performed     * by a single correctly rounded floating-point multiply to a     * member of the float value set.  See section 4.2.3 of     * <cite>The Java&trade; Language Specification</cite>     * for a discussion of floating-point     * value sets. If the exponent of the result is between the     * {@code float}'s minimum exponent and maximum exponent, the     * answer is calculated exactly.  If the exponent of the result     * would be larger than {@code float}'s maximum exponent, an     * infinity is returned.  Note that if the result is subnormal,     * precision may be lost; that is, when {@code scalb(x, n)}     * is subnormal, {@code scalb(scalb(x, n), -n)} may not equal     * <i>x</i>.  When the result is non-NaN, the result has the same     * sign as {@code f}.     *     *<p>     * Special cases:     * <ul>     * <li> If the first argument is NaN, NaN is returned.     * <li> If the first argument is infinite, then an infinity of the     * same sign is returned.     * <li> If the first argument is zero, then a zero of the same     * sign is returned.     * </ul>     *     * @param f number to be scaled by a power of two.     * @param scale_factor power of 2 used to scale {@code f}     * @return {@code f * }2<sup>{@code scale_factor}</sup>     * @author Joseph D. Darcy     */     public static float scalb(float f, int scale_factor) {        // magnitude of a power of two so large that scaling a finite        // nonzero value by it would be guaranteed to over or        // underflow; due to rounding, scaling down takes takes an        // additional power of two which is reflected here        final int MAX_SCALE = FloatConsts.MAX_EXPONENT + -FloatConsts.MIN_EXPONENT +                              FloatConsts.SIGNIFICAND_WIDTH + 1;         // Make sure scaling factor is in a reasonable range        scale_factor = Math.max(Math.min(scale_factor, MAX_SCALE), -MAX_SCALE);         /*         * Since + MAX_SCALE for float fits well within the double         * exponent range and + float -> double conversion is exact         * the multiplication below will be exact. Therefore, the         * rounding that occurs when the double product is cast to         * float will be the correctly rounded float result.  Since         * all operations other than the final multiply will be exact,         * it is not necessary to declare this method strictfp.         */        return (float)((double)f*powerOfTwoD(scale_factor));    }     /**     * Returns the floating-point number adjacent to the first     * argument in the direction of the second argument.  If both     * arguments compare as equal the second argument is returned.     *     * <p>     * Special cases:     * <ul>     * <li> If either argument is a NaN, then NaN is returned.     *     * <li> If both arguments are signed zeros, {@code direction}     * is returned unchanged (as implied by the requirement of     * returning the second argument if the arguments compare as     * equal).     *     * <li> If {@code start} is     * &plusmn;{@code Double.MIN_VALUE} and {@code direction}     * has a value such that the result should have a smaller     * magnitude, then a zero with the same sign as {@code start}     * is returned.     *     * <li> If {@code start} is infinite and     * {@code direction} has a value such that the result should     * have a smaller magnitude, {@code Double.MAX_VALUE} with the     * same sign as {@code start} is returned.     *     * <li> If {@code start} is equal to &plusmn;     * {@code Double.MAX_VALUE} and {@code direction} has a     * value such that the result should have a larger magnitude, an     * infinity with same sign as {@code start} is returned.     * </ul>     *     * @param start     starting floating-point value     * @param direction value indicating which of     * {@code start}'s neighbors or {@code start} should     * be returned     * @return The floating-point number adjacent to {@code start} in the     * direction of {@code direction}.     * @author Joseph D. Darcy     */    public static double nextAfter(double start, double direction) {        /*         * The cases:         *         * nextAfter(+infinity, 0)  == MAX_VALUE         * nextAfter(+infinity, +infinity)  == +infinity         * nextAfter(-infinity, 0)  == -MAX_VALUE         * nextAfter(-infinity, -infinity)  == -infinity         *         * are naturally handled without any additional testing         */         // First check for NaN values        if (isNaN(start) || isNaN(direction)) {            // return a NaN derived from the input NaN(s)            return start + direction;        } else if (start == direction) {            return direction;        } else {        // start > direction or start < direction            // Add +0.0 to get rid of a -0.0 (+0.0 + -0.0 => +0.0)            // then bitwise convert start to integer.            long transducer = Double.doubleToRawLongBits(start + 0.0d);             /*             * IEEE 754 floating-point numbers are lexicographically             * ordered if treated as signed- magnitude integers .             * Since Java's integers are two's complement,             * incrementing" the two's complement representation of a             * logically negative floating-point value *decrements*             * the signed-magnitude representation. Therefore, when             * the integer representation of a floating-point values             * is less than zero, the adjustment to the representation             * is in the opposite direction than would be expected at             * first .             */            if (direction > start) { // Calculate next greater value                transducer = transducer + (transducer >= 0L ? 1L:-1L);            } else  { // Calculate next lesser value                assert direction < start;                if (transducer > 0L)                    --transducer;                else                    if (transducer < 0L )                        ++transducer;                    /*                     * transducer==0, the result is -MIN_VALUE                     *                     * The transition from zero (implicitly                     * positive) to the smallest negative                     * signed magnitude value must be done                     * explicitly.                     */                    else                        transducer = DoubleConsts.SIGN_BIT_MASK | 1L;            }             return Double.longBitsToDouble(transducer);        }    }     /**     * Returns the floating-point number adjacent to the first     * argument in the direction of the second argument.  If both     * arguments compare as equal, the second argument is returned.     *     * <p>     * Special cases:     * <ul>     * <li> If either argument is a NaN, then NaN is returned.     *     * <li> If both arguments are signed zeros, a {@code float}     * zero with the same sign as {@code direction} is returned     * (as implied by the requirement of returning the second argument     * if the arguments compare as equal).     *     * <li> If {@code start} is     * &plusmn;{@code Float.MIN_VALUE} and {@code direction}     * has a value such that the result should have a smaller     * magnitude, then a zero with the same sign as {@code start}     * is returned.     *     * <li> If {@code start} is infinite and     * {@code direction} has a value such that the result should     * have a smaller magnitude, {@code Float.MAX_VALUE} with the     * same sign as {@code start} is returned.     *     * <li> If {@code start} is equal to &plusmn;     * {@code Float.MAX_VALUE} and {@code direction} has a     * value such that the result should have a larger magnitude, an     * infinity with same sign as {@code start} is returned.     * </ul>     *     * @param start     starting floating-point value     * @param direction value indicating which of     * {@code start}'s neighbors or {@code start} should     * be returned     * @return The floating-point number adjacent to {@code start} in the     * direction of {@code direction}.     * @author Joseph D. Darcy     */     public static float nextAfter(float start, double direction) {        /*         * The cases:         *         * nextAfter(+infinity, 0)  == MAX_VALUE         * nextAfter(+infinity, +infinity)  == +infinity         * nextAfter(-infinity, 0)  == -MAX_VALUE         * nextAfter(-infinity, -infinity)  == -infinity         *         * are naturally handled without any additional testing         */         // First check for NaN values        if (isNaN(start) || isNaN(direction)) {            // return a NaN derived from the input NaN(s)            return start + (float)direction;        } else if (start == direction) {            return (float)direction;        } else {        // start > direction or start < direction            // Add +0.0 to get rid of a -0.0 (+0.0 + -0.0 => +0.0)            // then bitwise convert start to integer.            int transducer = Float.floatToRawIntBits(start + 0.0f);             /*             * IEEE 754 floating-point numbers are lexicographically             * ordered if treated as signed- magnitude integers .             * Since Java's integers are two's complement,             * incrementing" the two's complement representation of a             * logically negative floating-point value *decrements*             * the signed-magnitude representation. Therefore, when             * the integer representation of a floating-point values             * is less than zero, the adjustment to the representation             * is in the opposite direction than would be expected at             * first.             */            if (direction > start) {// Calculate next greater value                transducer = transducer + (transducer >= 0 ? 1:-1);            } else  { // Calculate next lesser value                assert direction < start;                if (transducer > 0)                    --transducer;                else                    if (transducer < 0 )                        ++transducer;                    /*                     * transducer==0, the result is -MIN_VALUE                     *                     * The transition from zero (implicitly                     * positive) to the smallest negative                     * signed magnitude value must be done                     * explicitly.                     */                    else                        transducer = FloatConsts.SIGN_BIT_MASK | 1;            }             return Float.intBitsToFloat(transducer);        }    }     /**     * Returns the floating-point value adjacent to {@code d} in     * the direction of positive infinity.  This method is     * semantically equivalent to {@code nextAfter(d,     * Double.POSITIVE_INFINITY)}; however, a {@code nextUp}     * implementation may run faster than its equivalent     * {@code nextAfter} call.     *     * <p>Special Cases:     * <ul>     * <li> If the argument is NaN, the result is NaN.     *     * <li> If the argument is positive infinity, the result is     * positive infinity.     *     * <li> If the argument is zero, the result is     * {@code Double.MIN_VALUE}     *     * </ul>     *     * @param d  starting floating-point value     * @return The adjacent floating-point value closer to positive     * infinity.     * @author Joseph D. Darcy     */    public static double nextUp(double d) {        if( isNaN(d) || d == Double.POSITIVE_INFINITY)            return d;        else {            d += 0.0d;            return Double.longBitsToDouble(Double.doubleToRawLongBits(d) +                                           ((d >= 0.0d)?+1L:-1L));        }    }     /**     * Returns the floating-point value adjacent to {@code f} in     * the direction of positive infinity.  This method is     * semantically equivalent to {@code nextAfter(f,     * Double.POSITIVE_INFINITY)}; however, a {@code nextUp}     * implementation may run faster than its equivalent     * {@code nextAfter} call.     *     * <p>Special Cases:     * <ul>     * <li> If the argument is NaN, the result is NaN.     *     * <li> If the argument is positive infinity, the result is     * positive infinity.     *     * <li> If the argument is zero, the result is     * {@code Float.MIN_VALUE}     *     * </ul>     *     * @param f  starting floating-point value     * @return The adjacent floating-point value closer to positive     * infinity.     * @author Joseph D. Darcy     */     public static float nextUp(float f) {        if( isNaN(f) || f == FloatConsts.POSITIVE_INFINITY)            return f;        else {            f += 0.0f;            return Float.intBitsToFloat(Float.floatToRawIntBits(f) +                                        ((f >= 0.0f)?+1:-1));        }    }     /**     * Returns the floating-point value adjacent to {@code d} in     * the direction of negative infinity.  This method is     * semantically equivalent to {@code nextAfter(d,     * Double.NEGATIVE_INFINITY)}; however, a     * {@code nextDown} implementation may run faster than its     * equivalent {@code nextAfter} call.     *     * <p>Special Cases:     * <ul>     * <li> If the argument is NaN, the result is NaN.     *     * <li> If the argument is negative infinity, the result is     * negative infinity.     *     * <li> If the argument is zero, the result is     * {@code -Double.MIN_VALUE}     *     * </ul>     *     * @param d  starting floating-point value     * @return The adjacent floating-point value closer to negative     * infinity.     * @author Joseph D. Darcy     */    public static double nextDown(double d) {        if( isNaN(d) || d == Double.NEGATIVE_INFINITY)            return d;        else {            if (d == 0.0)                return -Double.MIN_VALUE;            else                return Double.longBitsToDouble(Double.doubleToRawLongBits(d) +                                               ((d > 0.0d)?-1L:+1L));        }    } 

Lines 501–1000 of 1215. Previous lines