Home | History | Annotate | Download | only in primitives
      1 /*
      2  * Copyright (C) 2008 The Guava Authors
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  * http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.google.common.primitives;
     18 
     19 import static com.google.common.base.Preconditions.checkArgument;
     20 import static com.google.common.base.Preconditions.checkElementIndex;
     21 import static com.google.common.base.Preconditions.checkNotNull;
     22 import static com.google.common.base.Preconditions.checkPositionIndexes;
     23 import static java.lang.Double.NEGATIVE_INFINITY;
     24 import static java.lang.Double.POSITIVE_INFINITY;
     25 
     26 import com.google.common.annotations.Beta;
     27 import com.google.common.annotations.GwtCompatible;
     28 import com.google.common.annotations.GwtIncompatible;
     29 import com.google.common.base.Converter;
     30 
     31 import java.io.Serializable;
     32 import java.util.AbstractList;
     33 import java.util.Arrays;
     34 import java.util.Collection;
     35 import java.util.Collections;
     36 import java.util.Comparator;
     37 import java.util.List;
     38 import java.util.RandomAccess;
     39 import java.util.regex.Pattern;
     40 
     41 import javax.annotation.Nullable;
     42 
     43 /**
     44  * Static utility methods pertaining to {@code double} primitives, that are not
     45  * already found in either {@link Double} or {@link Arrays}.
     46  *
     47  * <p>See the Guava User Guide article on <a href=
     48  * "http://code.google.com/p/guava-libraries/wiki/PrimitivesExplained">
     49  * primitive utilities</a>.
     50  *
     51  * @author Kevin Bourrillion
     52  * @since 1.0
     53  */
     54 @GwtCompatible(emulated = true)
     55 public final class Doubles {
     56   private Doubles() {}
     57 
     58   /**
     59    * The number of bytes required to represent a primitive {@code double}
     60    * value.
     61    *
     62    * @since 10.0
     63    */
     64   public static final int BYTES = Double.SIZE / Byte.SIZE;
     65 
     66   /**
     67    * Returns a hash code for {@code value}; equal to the result of invoking
     68    * {@code ((Double) value).hashCode()}.
     69    *
     70    * @param value a primitive {@code double} value
     71    * @return a hash code for the value
     72    */
     73   public static int hashCode(double value) {
     74     return ((Double) value).hashCode();
     75     // TODO(kevinb): do it this way when we can (GWT problem):
     76     // long bits = Double.doubleToLongBits(value);
     77     // return (int) (bits ^ (bits >>> 32));
     78   }
     79 
     80   /**
     81    * Compares the two specified {@code double} values. The sign of the value
     82    * returned is the same as that of <code>((Double) a).{@linkplain
     83    * Double#compareTo compareTo}(b)</code>. As with that method, {@code NaN} is
     84    * treated as greater than all other values, and {@code 0.0 > -0.0}.
     85    *
     86    * <p><b>Note:</b> this method simply delegates to the JDK method {@link
     87    * Double#compare}. It is provided for consistency with the other primitive
     88    * types, whose compare methods were not added to the JDK until JDK 7.
     89    *
     90    * @param a the first {@code double} to compare
     91    * @param b the second {@code double} to compare
     92    * @return a negative value if {@code a} is less than {@code b}; a positive
     93    *     value if {@code a} is greater than {@code b}; or zero if they are equal
     94    */
     95   public static int compare(double a, double b) {
     96     return Double.compare(a, b);
     97   }
     98 
     99   /**
    100    * Returns {@code true} if {@code value} represents a real number. This is
    101    * equivalent to, but not necessarily implemented as,
    102    * {@code !(Double.isInfinite(value) || Double.isNaN(value))}.
    103    *
    104    * @since 10.0
    105    */
    106   public static boolean isFinite(double value) {
    107     return NEGATIVE_INFINITY < value & value < POSITIVE_INFINITY;
    108   }
    109 
    110   /**
    111    * Returns {@code true} if {@code target} is present as an element anywhere in
    112    * {@code array}. Note that this always returns {@code false} when {@code
    113    * target} is {@code NaN}.
    114    *
    115    * @param array an array of {@code double} values, possibly empty
    116    * @param target a primitive {@code double} value
    117    * @return {@code true} if {@code array[i] == target} for some value of {@code
    118    *     i}
    119    */
    120   public static boolean contains(double[] array, double target) {
    121     for (double value : array) {
    122       if (value == target) {
    123         return true;
    124       }
    125     }
    126     return false;
    127   }
    128 
    129   /**
    130    * Returns the index of the first appearance of the value {@code target} in
    131    * {@code array}. Note that this always returns {@code -1} when {@code target}
    132    * is {@code NaN}.
    133    *
    134    * @param array an array of {@code double} values, possibly empty
    135    * @param target a primitive {@code double} value
    136    * @return the least index {@code i} for which {@code array[i] == target}, or
    137    *     {@code -1} if no such index exists.
    138    */
    139   public static int indexOf(double[] array, double target) {
    140     return indexOf(array, target, 0, array.length);
    141   }
    142 
    143   // TODO(kevinb): consider making this public
    144   private static int indexOf(
    145       double[] array, double target, int start, int end) {
    146     for (int i = start; i < end; i++) {
    147       if (array[i] == target) {
    148         return i;
    149       }
    150     }
    151     return -1;
    152   }
    153 
    154   /**
    155    * Returns the start position of the first occurrence of the specified {@code
    156    * target} within {@code array}, or {@code -1} if there is no such occurrence.
    157    *
    158    * <p>More formally, returns the lowest index {@code i} such that {@code
    159    * java.util.Arrays.copyOfRange(array, i, i + target.length)} contains exactly
    160    * the same elements as {@code target}.
    161    *
    162    * <p>Note that this always returns {@code -1} when {@code target} contains
    163    * {@code NaN}.
    164    *
    165    * @param array the array to search for the sequence {@code target}
    166    * @param target the array to search for as a sub-sequence of {@code array}
    167    */
    168   public static int indexOf(double[] array, double[] target) {
    169     checkNotNull(array, "array");
    170     checkNotNull(target, "target");
    171     if (target.length == 0) {
    172       return 0;
    173     }
    174 
    175     outer:
    176     for (int i = 0; i < array.length - target.length + 1; i++) {
    177       for (int j = 0; j < target.length; j++) {
    178         if (array[i + j] != target[j]) {
    179           continue outer;
    180         }
    181       }
    182       return i;
    183     }
    184     return -1;
    185   }
    186 
    187   /**
    188    * Returns the index of the last appearance of the value {@code target} in
    189    * {@code array}. Note that this always returns {@code -1} when {@code target}
    190    * is {@code NaN}.
    191    *
    192    * @param array an array of {@code double} values, possibly empty
    193    * @param target a primitive {@code double} value
    194    * @return the greatest index {@code i} for which {@code array[i] == target},
    195    *     or {@code -1} if no such index exists.
    196    */
    197   public static int lastIndexOf(double[] array, double target) {
    198     return lastIndexOf(array, target, 0, array.length);
    199   }
    200 
    201   // TODO(kevinb): consider making this public
    202   private static int lastIndexOf(
    203       double[] array, double target, int start, int end) {
    204     for (int i = end - 1; i >= start; i--) {
    205       if (array[i] == target) {
    206         return i;
    207       }
    208     }
    209     return -1;
    210   }
    211 
    212   /**
    213    * Returns the least value present in {@code array}, using the same rules of
    214    * comparison as {@link Math#min(double, double)}.
    215    *
    216    * @param array a <i>nonempty</i> array of {@code double} values
    217    * @return the value present in {@code array} that is less than or equal to
    218    *     every other value in the array
    219    * @throws IllegalArgumentException if {@code array} is empty
    220    */
    221   public static double min(double... array) {
    222     checkArgument(array.length > 0);
    223     double min = array[0];
    224     for (int i = 1; i < array.length; i++) {
    225       min = Math.min(min, array[i]);
    226     }
    227     return min;
    228   }
    229 
    230   /**
    231    * Returns the greatest value present in {@code array}, using the same rules
    232    * of comparison as {@link Math#max(double, double)}.
    233    *
    234    * @param array a <i>nonempty</i> array of {@code double} values
    235    * @return the value present in {@code array} that is greater than or equal to
    236    *     every other value in the array
    237    * @throws IllegalArgumentException if {@code array} is empty
    238    */
    239   public static double max(double... array) {
    240     checkArgument(array.length > 0);
    241     double max = array[0];
    242     for (int i = 1; i < array.length; i++) {
    243       max = Math.max(max, array[i]);
    244     }
    245     return max;
    246   }
    247 
    248   /**
    249    * Returns the values from each provided array combined into a single array.
    250    * For example, {@code concat(new double[] {a, b}, new double[] {}, new
    251    * double[] {c}} returns the array {@code {a, b, c}}.
    252    *
    253    * @param arrays zero or more {@code double} arrays
    254    * @return a single array containing all the values from the source arrays, in
    255    *     order
    256    */
    257   public static double[] concat(double[]... arrays) {
    258     int length = 0;
    259     for (double[] array : arrays) {
    260       length += array.length;
    261     }
    262     double[] result = new double[length];
    263     int pos = 0;
    264     for (double[] array : arrays) {
    265       System.arraycopy(array, 0, result, pos, array.length);
    266       pos += array.length;
    267     }
    268     return result;
    269   }
    270 
    271   private static final class DoubleConverter
    272       extends Converter<String, Double> implements Serializable {
    273     static final DoubleConverter INSTANCE = new DoubleConverter();
    274 
    275     @Override
    276     protected Double doForward(String value) {
    277       return Double.valueOf(value);
    278     }
    279 
    280     @Override
    281     protected String doBackward(Double value) {
    282       return value.toString();
    283     }
    284 
    285     @Override
    286     public String toString() {
    287       return "Doubles.stringConverter()";
    288     }
    289 
    290     private Object readResolve() {
    291       return INSTANCE;
    292     }
    293     private static final long serialVersionUID = 1;
    294   }
    295 
    296   /**
    297    * Returns a serializable converter object that converts between strings and
    298    * doubles using {@link Double#valueOf} and {@link Double#toString()}.
    299    *
    300    * @since 16.0
    301    */
    302   @Beta
    303   public static Converter<String, Double> stringConverter() {
    304     return DoubleConverter.INSTANCE;
    305   }
    306 
    307   /**
    308    * Returns an array containing the same values as {@code array}, but
    309    * guaranteed to be of a specified minimum length. If {@code array} already
    310    * has a length of at least {@code minLength}, it is returned directly.
    311    * Otherwise, a new array of size {@code minLength + padding} is returned,
    312    * containing the values of {@code array}, and zeroes in the remaining places.
    313    *
    314    * @param array the source array
    315    * @param minLength the minimum length the returned array must guarantee
    316    * @param padding an extra amount to "grow" the array by if growth is
    317    *     necessary
    318    * @throws IllegalArgumentException if {@code minLength} or {@code padding} is
    319    *     negative
    320    * @return an array containing the values of {@code array}, with guaranteed
    321    *     minimum length {@code minLength}
    322    */
    323   public static double[] ensureCapacity(
    324       double[] array, int minLength, int padding) {
    325     checkArgument(minLength >= 0, "Invalid minLength: %s", minLength);
    326     checkArgument(padding >= 0, "Invalid padding: %s", padding);
    327     return (array.length < minLength)
    328         ? copyOf(array, minLength + padding)
    329         : array;
    330   }
    331 
    332   // Arrays.copyOf() requires Java 6
    333   private static double[] copyOf(double[] original, int length) {
    334     double[] copy = new double[length];
    335     System.arraycopy(original, 0, copy, 0, Math.min(original.length, length));
    336     return copy;
    337   }
    338 
    339   /**
    340    * Returns a string containing the supplied {@code double} values, converted
    341    * to strings as specified by {@link Double#toString(double)}, and separated
    342    * by {@code separator}. For example, {@code join("-", 1.0, 2.0, 3.0)} returns
    343    * the string {@code "1.0-2.0-3.0"}.
    344    *
    345    * <p>Note that {@link Double#toString(double)} formats {@code double}
    346    * differently in GWT sometimes.  In the previous example, it returns the
    347    * string {@code "1-2-3"}.
    348    *
    349    * @param separator the text that should appear between consecutive values in
    350    *     the resulting string (but not at the start or end)
    351    * @param array an array of {@code double} values, possibly empty
    352    */
    353   public static String join(String separator, double... array) {
    354     checkNotNull(separator);
    355     if (array.length == 0) {
    356       return "";
    357     }
    358 
    359     // For pre-sizing a builder, just get the right order of magnitude
    360     StringBuilder builder = new StringBuilder(array.length * 12);
    361     builder.append(array[0]);
    362     for (int i = 1; i < array.length; i++) {
    363       builder.append(separator).append(array[i]);
    364     }
    365     return builder.toString();
    366   }
    367 
    368   /**
    369    * Returns a comparator that compares two {@code double} arrays
    370    * lexicographically. That is, it compares, using {@link
    371    * #compare(double, double)}), the first pair of values that follow any
    372    * common prefix, or when one array is a prefix of the other, treats the
    373    * shorter array as the lesser. For example,
    374    * {@code [] < [1.0] < [1.0, 2.0] < [2.0]}.
    375    *
    376    * <p>The returned comparator is inconsistent with {@link
    377    * Object#equals(Object)} (since arrays support only identity equality), but
    378    * it is consistent with {@link Arrays#equals(double[], double[])}.
    379    *
    380    * @see <a href="http://en.wikipedia.org/wiki/Lexicographical_order">
    381    *     Lexicographical order article at Wikipedia</a>
    382    * @since 2.0
    383    */
    384   public static Comparator<double[]> lexicographicalComparator() {
    385     return LexicographicalComparator.INSTANCE;
    386   }
    387 
    388   private enum LexicographicalComparator implements Comparator<double[]> {
    389     INSTANCE;
    390 
    391     @Override
    392     public int compare(double[] left, double[] right) {
    393       int minLength = Math.min(left.length, right.length);
    394       for (int i = 0; i < minLength; i++) {
    395         int result = Doubles.compare(left[i], right[i]);
    396         if (result != 0) {
    397           return result;
    398         }
    399       }
    400       return left.length - right.length;
    401     }
    402   }
    403 
    404   /**
    405    * Returns an array containing each value of {@code collection}, converted to
    406    * a {@code double} value in the manner of {@link Number#doubleValue}.
    407    *
    408    * <p>Elements are copied from the argument collection as if by {@code
    409    * collection.toArray()}.  Calling this method is as thread-safe as calling
    410    * that method.
    411    *
    412    * @param collection a collection of {@code Number} instances
    413    * @return an array containing the same values as {@code collection}, in the
    414    *     same order, converted to primitives
    415    * @throws NullPointerException if {@code collection} or any of its elements
    416    *     is null
    417    * @since 1.0 (parameter was {@code Collection<Double>} before 12.0)
    418    */
    419   public static double[] toArray(Collection<? extends Number> collection) {
    420     if (collection instanceof DoubleArrayAsList) {
    421       return ((DoubleArrayAsList) collection).toDoubleArray();
    422     }
    423 
    424     Object[] boxedArray = collection.toArray();
    425     int len = boxedArray.length;
    426     double[] array = new double[len];
    427     for (int i = 0; i < len; i++) {
    428       // checkNotNull for GWT (do not optimize)
    429       array[i] = ((Number) checkNotNull(boxedArray[i])).doubleValue();
    430     }
    431     return array;
    432   }
    433 
    434   /**
    435    * Returns a fixed-size list backed by the specified array, similar to {@link
    436    * Arrays#asList(Object[])}. The list supports {@link List#set(int, Object)},
    437    * but any attempt to set a value to {@code null} will result in a {@link
    438    * NullPointerException}.
    439    *
    440    * <p>The returned list maintains the values, but not the identities, of
    441    * {@code Double} objects written to or read from it.  For example, whether
    442    * {@code list.get(0) == list.get(0)} is true for the returned list is
    443    * unspecified.
    444    *
    445    * <p>The returned list may have unexpected behavior if it contains {@code
    446    * NaN}, or if {@code NaN} is used as a parameter to any of its methods.
    447    *
    448    * @param backingArray the array to back the list
    449    * @return a list view of the array
    450    */
    451   public static List<Double> asList(double... backingArray) {
    452     if (backingArray.length == 0) {
    453       return Collections.emptyList();
    454     }
    455     return new DoubleArrayAsList(backingArray);
    456   }
    457 
    458   @GwtCompatible
    459   private static class DoubleArrayAsList extends AbstractList<Double>
    460       implements RandomAccess, Serializable {
    461     final double[] array;
    462     final int start;
    463     final int end;
    464 
    465     DoubleArrayAsList(double[] array) {
    466       this(array, 0, array.length);
    467     }
    468 
    469     DoubleArrayAsList(double[] array, int start, int end) {
    470       this.array = array;
    471       this.start = start;
    472       this.end = end;
    473     }
    474 
    475     @Override public int size() {
    476       return end - start;
    477     }
    478 
    479     @Override public boolean isEmpty() {
    480       return false;
    481     }
    482 
    483     @Override public Double get(int index) {
    484       checkElementIndex(index, size());
    485       return array[start + index];
    486     }
    487 
    488     @Override public boolean contains(Object target) {
    489       // Overridden to prevent a ton of boxing
    490       return (target instanceof Double)
    491           && Doubles.indexOf(array, (Double) target, start, end) != -1;
    492     }
    493 
    494     @Override public int indexOf(Object target) {
    495       // Overridden to prevent a ton of boxing
    496       if (target instanceof Double) {
    497         int i = Doubles.indexOf(array, (Double) target, start, end);
    498         if (i >= 0) {
    499           return i - start;
    500         }
    501       }
    502       return -1;
    503     }
    504 
    505     @Override public int lastIndexOf(Object target) {
    506       // Overridden to prevent a ton of boxing
    507       if (target instanceof Double) {
    508         int i = Doubles.lastIndexOf(array, (Double) target, start, end);
    509         if (i >= 0) {
    510           return i - start;
    511         }
    512       }
    513       return -1;
    514     }
    515 
    516     @Override public Double set(int index, Double element) {
    517       checkElementIndex(index, size());
    518       double oldValue = array[start + index];
    519       // checkNotNull for GWT (do not optimize)
    520       array[start + index] = checkNotNull(element);
    521       return oldValue;
    522     }
    523 
    524     @Override public List<Double> subList(int fromIndex, int toIndex) {
    525       int size = size();
    526       checkPositionIndexes(fromIndex, toIndex, size);
    527       if (fromIndex == toIndex) {
    528         return Collections.emptyList();
    529       }
    530       return new DoubleArrayAsList(array, start + fromIndex, start + toIndex);
    531     }
    532 
    533     @Override public boolean equals(Object object) {
    534       if (object == this) {
    535         return true;
    536       }
    537       if (object instanceof DoubleArrayAsList) {
    538         DoubleArrayAsList that = (DoubleArrayAsList) object;
    539         int size = size();
    540         if (that.size() != size) {
    541           return false;
    542         }
    543         for (int i = 0; i < size; i++) {
    544           if (array[start + i] != that.array[that.start + i]) {
    545             return false;
    546           }
    547         }
    548         return true;
    549       }
    550       return super.equals(object);
    551     }
    552 
    553     @Override public int hashCode() {
    554       int result = 1;
    555       for (int i = start; i < end; i++) {
    556         result = 31 * result + Doubles.hashCode(array[i]);
    557       }
    558       return result;
    559     }
    560 
    561     @Override public String toString() {
    562       StringBuilder builder = new StringBuilder(size() * 12);
    563       builder.append('[').append(array[start]);
    564       for (int i = start + 1; i < end; i++) {
    565         builder.append(", ").append(array[i]);
    566       }
    567       return builder.append(']').toString();
    568     }
    569 
    570     double[] toDoubleArray() {
    571       // Arrays.copyOfRange() is not available under GWT
    572       int size = size();
    573       double[] result = new double[size];
    574       System.arraycopy(array, start, result, 0, size);
    575       return result;
    576     }
    577 
    578     private static final long serialVersionUID = 0;
    579   }
    580 
    581   /**
    582    * This is adapted from the regex suggested by {@link Double#valueOf(String)}
    583    * for prevalidating inputs.  All valid inputs must pass this regex, but it's
    584    * semantically fine if not all inputs that pass this regex are valid --
    585    * only a performance hit is incurred, not a semantics bug.
    586    */
    587   @GwtIncompatible("regular expressions")
    588   static final Pattern FLOATING_POINT_PATTERN = fpPattern();
    589 
    590   @GwtIncompatible("regular expressions")
    591   private static Pattern fpPattern() {
    592     String decimal = "(?:\\d++(?:\\.\\d*+)?|\\.\\d++)";
    593     String completeDec = decimal + "(?:[eE][+-]?\\d++)?[fFdD]?";
    594     String hex = "(?:\\p{XDigit}++(?:\\.\\p{XDigit}*+)?|\\.\\p{XDigit}++)";
    595     String completeHex = "0[xX]" + hex + "[pP][+-]?\\d++[fFdD]?";
    596     String fpPattern = "[+-]?(?:NaN|Infinity|" + completeDec + "|" + completeHex + ")";
    597     return Pattern.compile(fpPattern);
    598   }
    599 
    600   /**
    601    * Parses the specified string as a double-precision floating point value.
    602    * The ASCII character {@code '-'} (<code>'&#92;u002D'</code>) is recognized
    603    * as the minus sign.
    604    *
    605    * <p>Unlike {@link Double#parseDouble(String)}, this method returns
    606    * {@code null} instead of throwing an exception if parsing fails.
    607    * Valid inputs are exactly those accepted by {@link Double#valueOf(String)},
    608    * except that leading and trailing whitespace is not permitted.
    609    *
    610    * <p>This implementation is likely to be faster than {@code
    611    * Double.parseDouble} if many failures are expected.
    612    *
    613    * @param string the string representation of a {@code double} value
    614    * @return the floating point value represented by {@code string}, or
    615    *     {@code null} if {@code string} has a length of zero or cannot be
    616    *     parsed as a {@code double} value
    617    * @since 14.0
    618    */
    619   @GwtIncompatible("regular expressions")
    620   @Nullable
    621   @Beta
    622   public static Double tryParse(String string) {
    623     if (FLOATING_POINT_PATTERN.matcher(string).matches()) {
    624       // TODO(user): could be potentially optimized, but only with
    625       // extensive testing
    626       try {
    627         return Double.parseDouble(string);
    628       } catch (NumberFormatException e) {
    629         // Double.parseDouble has changed specs several times, so fall through
    630         // gracefully
    631       }
    632     }
    633     return null;
    634   }
    635 }
    636