001/*
002 * Copyright (C) 2011 The Guava Authors
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package ptolemy.util;
018
019// Remove the dependency on google classes.
020//import static com.google.common.base.Preconditions.checkArgument;
021import static java.lang.Double.MAX_EXPONENT;
022import static java.lang.Double.MIN_EXPONENT;
023import static java.lang.Double.POSITIVE_INFINITY;
024import static java.lang.Double.doubleToRawLongBits;
025import static java.lang.Double.isNaN;
026import static java.lang.Double.longBitsToDouble;
027import static java.lang.Math.getExponent;
028
029import java.math.BigInteger;
030
031/**
032 * Utilities for double primitives.
033 *
034 * This code is used by ptolemy.actor.util.Time to improve performance.
035 *
036 * @author Louis Wasserman, based on https://code.google.com/p/guava-libraries/source/browse/guava/src/com/google/common/math/DoubleUtils.java
037@version $Id$
038@since Ptolemy II 11.0
039 */
040public final class DoubleUtilities {
041    private DoubleUtilities() {
042    }
043
044    static double nextDown(double d) {
045        return -Math.nextUp(-d);
046    }
047
048    static long getSignificand(double d) {
049        // Remove check argument and replace with conditionals
050        // to remove dependency on google classes.
051        //checkArgument(isFinite(d), "not a normal value");
052        if (!isFinite(d)) {
053            throw new IllegalArgumentException("not a normal value");
054        }
055        int exponent = getExponent(d);
056        long bits = doubleToRawLongBits(d);
057        bits &= SIGNIFICAND_MASK;
058        return (exponent == MIN_EXPONENT - 1) ? bits << 1 : bits | IMPLICIT_BIT;
059    }
060
061    static boolean isFinite(double d) {
062        return getExponent(d) <= MAX_EXPONENT;
063    }
064
065    static boolean isNormal(double d) {
066        return getExponent(d) >= MIN_EXPONENT;
067    }
068
069    /*
070     * Returns x scaled by a power of 2 such that it is in the range [1, 2). Assumes x is positive,
071     * normal, and finite.
072     */
073    static double scaleNormalize(double x) {
074        long significand = doubleToRawLongBits(x) & SIGNIFICAND_MASK;
075        return longBitsToDouble(significand | ONE_BITS);
076    }
077
078    /** Convert a BigInteger to a double using a fast implementation.
079     *  @param x The BigInteger to be converted.
080     *  @return the value of the BigInteger as a double.
081     */
082    public static double bigToDouble(BigInteger x) {
083        // This is an extremely fast implementation of BigInteger.doubleValue().  JDK patch pending.
084        BigInteger absX = x.abs();
085        int exponent = absX.bitLength() - 1;
086        // exponent == floor(log2(abs(x)))
087        if (exponent < Long.SIZE - 1) {
088            return x.longValue();
089        } else if (exponent > MAX_EXPONENT) {
090            return x.signum() * POSITIVE_INFINITY;
091        }
092
093        /*
094         * We need the top SIGNIFICAND_BITS + 1 bits, including the "implicit" one bit. To make
095         * rounding easier, we pick out the top SIGNIFICAND_BITS + 2 bits, so we have one to help us
096         * round up or down. twiceSignifFloor will contain the top SIGNIFICAND_BITS + 2 bits, and
097         * signifFloor the top SIGNIFICAND_BITS + 1.
098         *
099         * It helps to consider the real number signif = absX * 2^(SIGNIFICAND_BITS - exponent).
100         */
101        int shift = exponent - SIGNIFICAND_BITS - 1;
102        long twiceSignifFloor = absX.shiftRight(shift).longValue();
103        long signifFloor = twiceSignifFloor >> 1;
104        signifFloor &= SIGNIFICAND_MASK; // remove the implied bit
105
106        /*
107         * We round up if either the fractional part of signif is strictly greater than 0.5 (which is
108         * true if the 0.5 bit is set and any lower bit is set), or if the fractional part of signif is
109         * >= 0.5 and signifFloor is odd (which is true if both the 0.5 bit and the 1 bit are set).
110         */
111        boolean increment = (twiceSignifFloor & 1) != 0
112                && ((signifFloor & 1) != 0 || absX.getLowestSetBit() < shift);
113        long signifRounded = increment ? signifFloor + 1 : signifFloor;
114        long bits = (long) ((exponent + EXPONENT_BIAS)) << SIGNIFICAND_BITS;
115        bits += signifRounded;
116        /*
117         * If signifRounded == 2^53, we'd need to set all of the significand bits to zero and add 1 to
118         * the exponent. This is exactly the behavior we get from just adding signifRounded to bits
119         * directly.  If the exponent is MAX_DOUBLE_EXPONENT, we round up (correctly) to
120         * Double.POSITIVE_INFINITY.
121         */
122        bits |= x.signum() & SIGN_MASK;
123        return longBitsToDouble(bits);
124    }
125
126    /**
127     * Returns its argument if it is non-negative, zero if it is negative.
128     * @param value The value to be checked.
129     * @return If value is non-negative, return the value.  If the value
130     * is negative, then return zero.
131     */
132    static double ensureNonNegative(double value) {
133        // Remove check argument and replace with conditionals
134        // to remove dependency on google classes.
135        //checkArgument(!isNaN(value));
136        if (isNaN(value)) {
137            throw new IllegalArgumentException("not a number");
138        }
139        if (value > 0.0) {
140            return value;
141        } else {
142            return 0.0;
143        }
144    }
145
146    ///////////////////////////////////////////////////////////////////
147    ////                    static variables                      ////
148
149    // The mask for the significand, according to the {@link
150    // Double#doubleToRawLongBits(double)} spec.
151    static final long SIGNIFICAND_MASK = 0x000fffffffffffffL;
152
153    // The mask for the exponent, according to the {@link
154    // Double#doubleToRawLongBits(double)} spec.
155    static final long EXPONENT_MASK = 0x7ff0000000000000L;
156
157    // The mask for the sign, according to the {@link
158    // Double#doubleToRawLongBits(double)} spec.
159    static final long SIGN_MASK = 0x8000000000000000L;
160
161    // The significands bits
162    static final int SIGNIFICAND_BITS = 52;
163
164    // The exponent bias
165    static final int EXPONENT_BIAS = 1023;
166
167    // The implicit 1 bit that is omitted in significands of normal doubles.
168    static final long IMPLICIT_BIT = SIGNIFICAND_MASK + 1;
169
170    ///////////////////////////////////////////////////////////////////
171    ////                      static private variables            ////
172
173    private static final long ONE_BITS = doubleToRawLongBits(1.0);
174}