001/*
002 * Copyright (C) 2008 The Guava Authors
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
005 * in compliance with the License. You may obtain a copy of the License at
006 *
007 * http://www.apache.org/licenses/LICENSE-2.0
008 *
009 * Unless required by applicable law or agreed to in writing, software distributed under the License
010 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
011 * or implied. See the License for the specific language governing permissions and limitations under
012 * the License.
013 */
014
015package com.google.common.primitives;
016
017import static com.google.common.base.Preconditions.checkArgument;
018import static com.google.common.base.Preconditions.checkElementIndex;
019import static com.google.common.base.Preconditions.checkNotNull;
020import static com.google.common.base.Preconditions.checkPositionIndexes;
021import static com.google.common.base.Strings.lenientFormat;
022import static java.lang.Double.parseDouble;
023import static java.lang.Math.floorMod;
024import static java.lang.System.arraycopy;
025import static java.util.Arrays.sort;
026import static java.util.Collections.emptyList;
027
028import com.google.common.annotations.GwtCompatible;
029import com.google.common.annotations.GwtIncompatible;
030import com.google.common.annotations.J2ktIncompatible;
031import com.google.common.base.Converter;
032import com.google.errorprone.annotations.InlineMe;
033import java.io.Serializable;
034import java.util.AbstractList;
035import java.util.Arrays;
036import java.util.Collection;
037import java.util.Comparator;
038import java.util.List;
039import java.util.RandomAccess;
040import java.util.Spliterator;
041import java.util.Spliterators;
042import org.jspecify.annotations.Nullable;
043
044/**
045 * Static utility methods pertaining to {@code double} primitives, that are not already found in
046 * either {@link Double} or {@link Arrays}.
047 *
048 * <p>See the Guava User Guide article on <a
049 * href="https://github.com/google/guava/wiki/PrimitivesExplained">primitive utilities</a>.
050 *
051 * @author Kevin Bourrillion
052 * @since 1.0
053 */
054@GwtCompatible
055public final class Doubles extends DoublesMethodsForWeb {
056  private Doubles() {}
057
058  /**
059   * The number of bytes required to represent a primitive {@code double} value.
060   *
061   * <p>Prefer {@link Double#BYTES} instead.
062   *
063   * @since 10.0
064   */
065  public static final int BYTES = Double.BYTES;
066
067  /**
068   * Represents the smallest {@code double} value that is strictly greater than zero. This is an
069   * alias for {@link Double#MIN_VALUE}, but has a name that more clearly expresses its meaning.
070   *
071   * <p><b>Note:</b> the most negative finite double value is {@code -Double.MAX_VALUE}.
072   *
073   * @since 33.8.0
074   */
075  public static final double MIN_POSITIVE_VALUE = Double.MIN_VALUE;
076
077  /**
078   * Returns a hash code for {@code value}; obsolete alternative to {@link Double#hashCode(double)}.
079   *
080   * @param value a primitive {@code double} value
081   * @return a hash code for the value
082   */
083  @InlineMe(replacement = "Double.hashCode(value)")
084  public static int hashCode(double value) {
085    return Double.hashCode(value);
086  }
087
088  /**
089   * Compares the two specified {@code double} values. The sign of the value returned is the same as
090   * that of <code>((Double) a).{@linkplain Double#compareTo compareTo}(b)</code>. As with that
091   * method, {@code NaN} is treated as greater than all other values, and {@code 0.0 > -0.0}.
092   *
093   * <p><b>Note:</b> this method simply delegates to the JDK method {@link Double#compare}. It is
094   * provided for consistency with the other primitive types, whose compare methods were not added
095   * to the JDK until JDK 7.
096   *
097   * @param a the first {@code double} to compare
098   * @param b the second {@code double} to compare
099   * @return a negative value if {@code a} is less than {@code b}; a positive value if {@code a} is
100   *     greater than {@code b}; or zero if they are equal
101   */
102  @InlineMe(replacement = "Double.compare(a, b)")
103  public static int compare(double a, double b) {
104    return Double.compare(a, b);
105  }
106
107  /**
108   * Returns {@code true} if {@code value} represents a real number. This is equivalent to, but not
109   * necessarily implemented as, {@code !(Double.isInfinite(value) || Double.isNaN(value))}.
110   *
111   * <p>Prefer {@link Double#isFinite(double)} instead.
112   *
113   * @since 10.0
114   */
115  @InlineMe(replacement = "Double.isFinite(value)")
116  public static boolean isFinite(double value) {
117    return Double.isFinite(value);
118  }
119
120  /**
121   * Returns {@code true} if {@code target} is present as an element anywhere in {@code array}. Note
122   * that this always returns {@code false} when {@code target} is {@code NaN}.
123   *
124   * @param array an array of {@code double} values, possibly empty
125   * @param target a primitive {@code double} value
126   * @return {@code true} if {@code array[i] == target} for some value of {@code i}
127   */
128  public static boolean contains(double[] array, double target) {
129    for (double value : array) {
130      if (value == target) {
131        return true;
132      }
133    }
134    return false;
135  }
136
137  /**
138   * Returns the index of the first appearance of the value {@code target} in {@code array}. Note
139   * that this always returns {@code -1} when {@code target} is {@code NaN}.
140   *
141   * @param array an array of {@code double} values, possibly empty
142   * @param target a primitive {@code double} value
143   * @return the least index {@code i} for which {@code array[i] == target}, or {@code -1} if no
144   *     such index exists.
145   */
146  public static int indexOf(double[] array, double target) {
147    return indexOf(array, target, 0, array.length);
148  }
149
150  // TODO(kevinb): consider making this public
151  private static int indexOf(double[] array, double target, int start, int end) {
152    for (int i = start; i < end; i++) {
153      if (array[i] == target) {
154        return i;
155      }
156    }
157    return -1;
158  }
159
160  /**
161   * Returns the start position of the first occurrence of the specified {@code target} within
162   * {@code array}, or {@code -1} if there is no such occurrence.
163   *
164   * <p>More formally, returns the lowest index {@code i} such that {@code Arrays.copyOfRange(array,
165   * i, i + target.length)} contains exactly the same elements as {@code target}.
166   *
167   * <p>Note that this always returns {@code -1} when {@code target} contains {@code NaN}.
168   *
169   * @param array the array to search for the sequence {@code target}
170   * @param target the array to search for as a sub-sequence of {@code array}
171   */
172  public static int indexOf(double[] array, double[] target) {
173    checkNotNull(array, "array");
174    checkNotNull(target, "target");
175    if (target.length == 0) {
176      return 0;
177    }
178
179    outer:
180    for (int i = 0; i < array.length - target.length + 1; i++) {
181      for (int j = 0; j < target.length; j++) {
182        if (array[i + j] != target[j]) {
183          continue outer;
184        }
185      }
186      return i;
187    }
188    return -1;
189  }
190
191  /**
192   * Returns the index of the last appearance of the value {@code target} in {@code array}. Note
193   * that this always returns {@code -1} when {@code target} is {@code NaN}.
194   *
195   * @param array an array of {@code double} values, possibly empty
196   * @param target a primitive {@code double} value
197   * @return the greatest index {@code i} for which {@code array[i] == target}, or {@code -1} if no
198   *     such index exists.
199   */
200  public static int lastIndexOf(double[] array, double target) {
201    return lastIndexOf(array, target, 0, array.length);
202  }
203
204  // TODO(kevinb): consider making this public
205  private static int lastIndexOf(double[] array, double target, int start, int end) {
206    for (int i = end - 1; i >= start; i--) {
207      if (array[i] == target) {
208        return i;
209      }
210    }
211    return -1;
212  }
213
214  /**
215   * Returns the least value present in {@code array}, using the same rules of comparison as {@link
216   * Math#min(double, double)}.
217   *
218   * @param array a <i>nonempty</i> array of {@code double} values
219   * @return the value present in {@code array} that is less than or equal to every other value in
220   *     the array
221   * @throws IllegalArgumentException if {@code array} is empty
222   */
223  @GwtIncompatible(
224      "Available in GWT! Annotation is to avoid conflict with GWT specialization of base class.")
225  public static double min(double... array) {
226    checkArgument(array.length > 0);
227    double min = array[0];
228    for (int i = 1; i < array.length; i++) {
229      min = Math.min(min, array[i]);
230    }
231    return min;
232  }
233
234  /**
235   * Returns the greatest value present in {@code array}, using the same rules of comparison as
236   * {@link Math#max(double, double)}.
237   *
238   * @param array a <i>nonempty</i> array of {@code double} values
239   * @return the value present in {@code array} that is greater than or equal to every other value
240   *     in the array
241   * @throws IllegalArgumentException if {@code array} is empty
242   */
243  @GwtIncompatible(
244      "Available in GWT! Annotation is to avoid conflict with GWT specialization of base class.")
245  public static double max(double... array) {
246    checkArgument(array.length > 0);
247    double max = array[0];
248    for (int i = 1; i < array.length; i++) {
249      max = Math.max(max, array[i]);
250    }
251    return max;
252  }
253
254  /**
255   * Returns the value nearest to {@code value} which is within the closed range {@code [min..max]}.
256   *
257   * <p>If {@code value} is within the range {@code [min..max]}, {@code value} is returned
258   * unchanged. If {@code value} is less than {@code min}, {@code min} is returned, and if {@code
259   * value} is greater than {@code max}, {@code max} is returned.
260   *
261   * <p><b>Java 21+ users:</b> Use {@link Math#clamp(double, double, double)} instead.
262   *
263   * @param value the {@code double} value to constrain
264   * @param min the lower bound (inclusive) of the range to constrain {@code value} to
265   * @param max the upper bound (inclusive) of the range to constrain {@code value} to
266   * @throws IllegalArgumentException if {@code min > max}
267   * @since 21.0
268   */
269  public static double constrainToRange(double value, double min, double max) {
270    // avoid auto-boxing by not using Preconditions.checkArgument(); see Guava issue 3984
271    // Reject NaN by testing for the good case (min <= max) instead of the bad (min > max).
272    if (min <= max) {
273      return Math.min(Math.max(value, min), max);
274    }
275    throw new IllegalArgumentException(
276        lenientFormat("min (%s) must be less than or equal to max (%s)", min, max));
277  }
278
279  /**
280   * Returns the values from each provided array combined into a single array. For example, {@code
281   * concat(new double[] {a, b}, new double[] {}, new double[] {c}} returns the array {@code {a, b,
282   * c}}.
283   *
284   * @param arrays zero or more {@code double} arrays
285   * @return a single array containing all the values from the source arrays, in order
286   * @throws IllegalArgumentException if the total number of elements in {@code arrays} does not fit
287   *     in an {@code int}
288   */
289  public static double[] concat(double[]... arrays) {
290    long length = 0;
291    for (double[] array : arrays) {
292      length += array.length;
293    }
294    double[] result = new double[checkNoOverflow(length)];
295    int pos = 0;
296    for (double[] array : arrays) {
297      arraycopy(array, 0, result, pos, array.length);
298      pos += array.length;
299    }
300    return result;
301  }
302
303  private static int checkNoOverflow(long result) {
304    checkArgument(
305        result == (int) result,
306        "the total number of elements (%s) in the arrays must fit in an int",
307        result);
308    return (int) result;
309  }
310
311  private static final class DoubleConverter extends Converter<String, Double>
312      implements Serializable {
313    static final Converter<String, Double> INSTANCE = new DoubleConverter();
314
315    @Override
316    protected Double doForward(String value) {
317      return Double.valueOf(value);
318    }
319
320    @Override
321    protected String doBackward(Double value) {
322      return value.toString();
323    }
324
325    @Override
326    public String toString() {
327      return "Doubles.stringConverter()";
328    }
329
330    private Object readResolve() {
331      return INSTANCE;
332    }
333
334    @GwtIncompatible @J2ktIncompatible private static final long serialVersionUID = 1;
335  }
336
337  /**
338   * Returns a serializable converter object that converts between strings and doubles using {@link
339   * Double#valueOf} and {@link Double#toString()}.
340   *
341   * @since 16.0
342   */
343  public static Converter<String, Double> stringConverter() {
344    return DoubleConverter.INSTANCE;
345  }
346
347  /**
348   * Returns an array containing the same values as {@code array}, but guaranteed to be of a
349   * specified minimum length. If {@code array} already has a length of at least {@code minLength},
350   * it is returned directly. Otherwise, a new array of size {@code minLength + padding} is
351   * returned, containing the values of {@code array}, and zeroes in the remaining places.
352   *
353   * @param array the source array
354   * @param minLength the minimum length the returned array must guarantee
355   * @param padding an extra amount to "grow" the array by if growth is necessary
356   * @throws IllegalArgumentException if {@code minLength} or {@code padding} is negative
357   * @return an array containing the values of {@code array}, with guaranteed minimum length {@code
358   *     minLength}
359   */
360  public static double[] ensureCapacity(double[] array, int minLength, int padding) {
361    checkArgument(minLength >= 0, "Invalid minLength: %s", minLength);
362    checkArgument(padding >= 0, "Invalid padding: %s", padding);
363    return (array.length < minLength) ? Arrays.copyOf(array, minLength + padding) : array;
364  }
365
366  /**
367   * Returns a string containing the supplied {@code double} values, converted to strings as
368   * specified by {@link Double#toString(double)}, and separated by {@code separator}. For example,
369   * {@code join("-", 1.0, 2.0, 3.0)} returns the string {@code "1.0-2.0-3.0"}.
370   *
371   * <p>Note that {@link Double#toString(double)} formats {@code double} differently in GWT
372   * sometimes. In the previous example, it returns the string {@code "1-2-3"}.
373   *
374   * @param separator the text that should appear between consecutive values in the resulting string
375   *     (but not at the start or end)
376   * @param array an array of {@code double} values, possibly empty
377   */
378  public static String join(String separator, double... array) {
379    checkNotNull(separator);
380    if (array.length == 0) {
381      return "";
382    }
383
384    // For pre-sizing a builder, just get the right order of magnitude
385    StringBuilder builder = new StringBuilder(array.length * 12);
386    builder.append(array[0]);
387    for (int i = 1; i < array.length; i++) {
388      builder.append(separator).append(array[i]);
389    }
390    return builder.toString();
391  }
392
393  /**
394   * Returns a comparator that compares two {@code double} arrays <a
395   * href="http://en.wikipedia.org/wiki/Lexicographical_order">lexicographically</a>. That is, it
396   * compares, using {@link #compare(double, double)}), the first pair of values that follow any
397   * common prefix, or when one array is a prefix of the other, treats the shorter array as the
398   * lesser. For example, {@code [] < [1.0] < [1.0, 2.0] < [2.0]}.
399   *
400   * <p>The returned comparator is inconsistent with {@link Object#equals(Object)} (since arrays
401   * support only identity equality), but it is consistent with {@link Arrays#equals(double[],
402   * double[])}.
403   *
404   * @since 2.0
405   */
406  public static Comparator<double[]> lexicographicalComparator() {
407    return LexicographicalComparator.INSTANCE;
408  }
409
410  private enum LexicographicalComparator implements Comparator<double[]> {
411    INSTANCE;
412
413    @Override
414    public int compare(double[] left, double[] right) {
415      int minLength = Math.min(left.length, right.length);
416      for (int i = 0; i < minLength; i++) {
417        int result = Double.compare(left[i], right[i]);
418        if (result != 0) {
419          return result;
420        }
421      }
422      return left.length - right.length;
423    }
424
425    @Override
426    public String toString() {
427      return "Doubles.lexicographicalComparator()";
428    }
429  }
430
431  /**
432   * Sorts the elements of {@code array} in descending order.
433   *
434   * <p>Note that this method uses the total order imposed by {@link Double#compare}, which treats
435   * all NaN values as equal and 0.0 as greater than -0.0.
436   *
437   * @since 23.1
438   */
439  public static void sortDescending(double[] array) {
440    checkNotNull(array);
441    sortDescending(array, 0, array.length);
442  }
443
444  /**
445   * Sorts the elements of {@code array} between {@code fromIndex} inclusive and {@code toIndex}
446   * exclusive in descending order.
447   *
448   * <p>Note that this method uses the total order imposed by {@link Double#compare}, which treats
449   * all NaN values as equal and 0.0 as greater than -0.0.
450   *
451   * @since 23.1
452   */
453  public static void sortDescending(double[] array, int fromIndex, int toIndex) {
454    checkNotNull(array);
455    checkPositionIndexes(fromIndex, toIndex, array.length);
456    sort(array, fromIndex, toIndex);
457    reverse(array, fromIndex, toIndex);
458  }
459
460  /**
461   * Reverses the elements of {@code array}. This is equivalent to {@code
462   * Collections.reverse(Doubles.asList(array))}, but is likely to be more efficient.
463   *
464   * @since 23.1
465   */
466  public static void reverse(double[] array) {
467    checkNotNull(array);
468    reverse(array, 0, array.length);
469  }
470
471  /**
472   * Reverses the elements of {@code array} between {@code fromIndex} inclusive and {@code toIndex}
473   * exclusive. This is equivalent to {@code
474   * Collections.reverse(Doubles.asList(array).subList(fromIndex, toIndex))}, but is likely to be
475   * more efficient.
476   *
477   * @throws IndexOutOfBoundsException if {@code fromIndex < 0}, {@code toIndex > array.length}, or
478   *     {@code toIndex > fromIndex}
479   * @since 23.1
480   */
481  public static void reverse(double[] array, int fromIndex, int toIndex) {
482    checkNotNull(array);
483    checkPositionIndexes(fromIndex, toIndex, array.length);
484    for (int i = fromIndex, j = toIndex - 1; i < j; i++, j--) {
485      double tmp = array[i];
486      array[i] = array[j];
487      array[j] = tmp;
488    }
489  }
490
491  /**
492   * Performs a right rotation of {@code array} of "distance" places, so that the first element is
493   * moved to index "distance", and the element at index {@code i} ends up at index {@code (distance
494   * + i) mod array.length}. This is equivalent to {@code Collections.rotate(Bytes.asList(array),
495   * distance)}, but is considerably faster and avoids allocation and garbage collection.
496   *
497   * <p>The provided "distance" may be negative, which will rotate left.
498   *
499   * @since 32.0.0
500   */
501  public static void rotate(double[] array, int distance) {
502    rotate(array, distance, 0, array.length);
503  }
504
505  /**
506   * Performs a right rotation of {@code array} between {@code fromIndex} inclusive and {@code
507   * toIndex} exclusive. This is equivalent to {@code
508   * Collections.rotate(Bytes.asList(array).subList(fromIndex, toIndex), distance)}, but is
509   * considerably faster and avoids allocations and garbage collection.
510   *
511   * <p>The provided "distance" may be negative, which will rotate left.
512   *
513   * @throws IndexOutOfBoundsException if {@code fromIndex < 0}, {@code toIndex > array.length}, or
514   *     {@code toIndex > fromIndex}
515   * @since 32.0.0
516   */
517  public static void rotate(double[] array, int distance, int fromIndex, int toIndex) {
518    // See Ints.rotate for more details about possible algorithms here.
519    checkNotNull(array);
520    checkPositionIndexes(fromIndex, toIndex, array.length);
521    int length = toIndex - fromIndex;
522    if (length <= 1) {
523      return;
524    }
525
526    // Map the given distance to an equivalent, non-negative value less than "length".
527    distance = floorMod(distance, length);
528    if (distance == 0) {
529      return;
530    }
531    // The current index of what will become the first element of the rotated section.
532    int newFirstIndex = toIndex - distance;
533
534    reverse(array, fromIndex, newFirstIndex);
535    reverse(array, newFirstIndex, toIndex);
536    reverse(array, fromIndex, toIndex);
537  }
538
539  /**
540   * Returns an array containing each value of {@code collection}, converted to a {@code double}
541   * value in the manner of {@link Number#doubleValue}.
542   *
543   * <p>Elements are copied from the argument collection as if by {@code collection.toArray()}.
544   * Calling this method is as thread-safe as calling that method.
545   *
546   * @param collection a collection of {@code Number} instances
547   * @return an array containing the same values as {@code collection}, in the same order, converted
548   *     to primitives
549   * @throws NullPointerException if {@code collection} or any of its elements is null
550   * @since 1.0 (parameter was {@code Collection<Double>} before 12.0)
551   */
552  public static double[] toArray(Collection<? extends Number> collection) {
553    if (collection instanceof DoubleArrayAsList) {
554      return ((DoubleArrayAsList) collection).toDoubleArray();
555    }
556
557    Object[] boxedArray = collection.toArray();
558    int len = boxedArray.length;
559    double[] array = new double[len];
560    for (int i = 0; i < len; i++) {
561      // checkNotNull for GWT (do not optimize)
562      array[i] = ((Number) checkNotNull(boxedArray[i])).doubleValue();
563    }
564    return array;
565  }
566
567  /**
568   * Returns a fixed-size list backed by the specified array, similar to {@link
569   * Arrays#asList(Object[])}. The list supports {@link List#set(int, Object)}, but any attempt to
570   * set a value to {@code null} will result in a {@link NullPointerException}.
571   *
572   * <p>The returned list maintains the values, but not the identities, of {@code Double} objects
573   * written to or read from it. For example, whether {@code list.get(0) == list.get(0)} is true for
574   * the returned list is unspecified.
575   *
576   * <p>The returned list may have unexpected behavior if it contains {@code NaN}, or if {@code NaN}
577   * is used as a parameter to any of its methods.
578   *
579   * <p>The returned list is serializable.
580   *
581   * <p><b>Note:</b> when possible, you should represent your data as an {@link
582   * ImmutableDoubleArray} instead, which has an {@link ImmutableDoubleArray#asList asList} view.
583   *
584   * @param backingArray the array to back the list
585   * @return a list view of the array
586   */
587  public static List<Double> asList(double... backingArray) {
588    if (backingArray.length == 0) {
589      return emptyList();
590    }
591    return new DoubleArrayAsList(backingArray);
592  }
593
594  private static final class DoubleArrayAsList extends AbstractList<Double>
595      implements RandomAccess, Serializable {
596    final double[] array;
597    final int start;
598    final int end;
599
600    DoubleArrayAsList(double[] array) {
601      this(array, 0, array.length);
602    }
603
604    DoubleArrayAsList(double[] array, int start, int end) {
605      this.array = array;
606      this.start = start;
607      this.end = end;
608    }
609
610    @Override
611    public int size() {
612      return end - start;
613    }
614
615    @Override
616    public boolean isEmpty() {
617      return false;
618    }
619
620    @Override
621    public Double get(int index) {
622      checkElementIndex(index, size());
623      return array[start + index];
624    }
625
626    @Override
627    public Spliterator.OfDouble spliterator() {
628      return Spliterators.spliterator(array, start, end, 0);
629    }
630
631    @Override
632    public boolean contains(@Nullable Object target) {
633      // Overridden to prevent a ton of boxing
634      return (target instanceof Double)
635          && Doubles.indexOf(array, (Double) target, start, end) != -1;
636    }
637
638    @Override
639    public int indexOf(@Nullable Object target) {
640      // Overridden to prevent a ton of boxing
641      if (target instanceof Double) {
642        int i = Doubles.indexOf(array, (Double) target, start, end);
643        if (i >= 0) {
644          return i - start;
645        }
646      }
647      return -1;
648    }
649
650    @Override
651    public int lastIndexOf(@Nullable Object target) {
652      // Overridden to prevent a ton of boxing
653      if (target instanceof Double) {
654        int i = Doubles.lastIndexOf(array, (Double) target, start, end);
655        if (i >= 0) {
656          return i - start;
657        }
658      }
659      return -1;
660    }
661
662    @Override
663    public Double set(int index, Double element) {
664      checkElementIndex(index, size());
665      double oldValue = array[start + index];
666      // checkNotNull for GWT (do not optimize)
667      array[start + index] = checkNotNull(element);
668      return oldValue;
669    }
670
671    @Override
672    public List<Double> subList(int fromIndex, int toIndex) {
673      int size = size();
674      checkPositionIndexes(fromIndex, toIndex, size);
675      if (fromIndex == toIndex) {
676        return emptyList();
677      }
678      return new DoubleArrayAsList(array, start + fromIndex, start + toIndex);
679    }
680
681    @Override
682    public boolean equals(@Nullable Object object) {
683      if (object == this) {
684        return true;
685      }
686      if (object instanceof DoubleArrayAsList) {
687        DoubleArrayAsList that = (DoubleArrayAsList) object;
688        int size = size();
689        if (that.size() != size) {
690          return false;
691        }
692        for (int i = 0; i < size; i++) {
693          if (array[start + i] != that.array[that.start + i]) {
694            return false;
695          }
696        }
697        return true;
698      }
699      return super.equals(object);
700    }
701
702    @Override
703    public int hashCode() {
704      int result = 1;
705      for (int i = start; i < end; i++) {
706        result = 31 * result + Double.hashCode(array[i]);
707      }
708      return result;
709    }
710
711    @Override
712    public String toString() {
713      StringBuilder builder = new StringBuilder(size() * 12);
714      builder.append('[').append(array[start]);
715      for (int i = start + 1; i < end; i++) {
716        builder.append(", ").append(array[i]);
717      }
718      return builder.append(']').toString();
719    }
720
721    double[] toDoubleArray() {
722      return Arrays.copyOfRange(array, start, end);
723    }
724
725    @GwtIncompatible @J2ktIncompatible private static final long serialVersionUID = 0;
726  }
727
728  /**
729   * This is adapted from the regex suggested by {@link Double#valueOf(String)} for prevalidating
730   * inputs. All valid inputs must pass this regex, but it's semantically fine if not all inputs
731   * that pass this regex are valid -- only a performance hit is incurred, not a semantics bug.
732   */
733  @GwtIncompatible // regular expressions
734  static final
735  java.util.regex.Pattern
736      FLOATING_POINT_PATTERN = fpPattern();
737
738  @GwtIncompatible // regular expressions
739  private static
740  java.util.regex.Pattern
741      fpPattern() {
742    /*
743     * We use # instead of * for possessive quantifiers. This lets us strip them out when building
744     * the regex for RE2 (which doesn't support them) but leave them in when building it for
745     * java.util.regex (where we want them in order to avoid catastrophic backtracking).
746     */
747    String decimal = "(?:\\d+#(?:\\.\\d*#)?|\\.\\d+#)";
748    String completeDec = decimal + "(?:[eE][+-]?\\d+#)?[fFdD]?";
749    String hex = "(?:[0-9a-fA-F]+#(?:\\.[0-9a-fA-F]*#)?|\\.[0-9a-fA-F]+#)";
750    String completeHex = "0[xX]" + hex + "[pP][+-]?\\d+#[fFdD]?";
751    String fpPattern = "[+-]?(?:NaN|Infinity|" + completeDec + "|" + completeHex + ")";
752    fpPattern =
753        fpPattern.replace(
754            "#",
755            "+"
756            );
757    return
758    java.util.regex.Pattern
759        .compile(fpPattern);
760  }
761
762  /**
763   * Parses the specified string as a double-precision floating point value. The ASCII character
764   * {@code '-'} (U+002D) is recognized as the minus sign.
765   *
766   * <p>Unlike {@link Double#parseDouble(String)}, this method returns {@code null} instead of
767   * throwing an exception if parsing fails. Valid inputs are exactly those accepted by {@link
768   * Double#valueOf(String)}, except that leading and trailing whitespace is not permitted.
769   *
770   * <p>This implementation is likely to be faster than {@code Double.parseDouble} if many failures
771   * are expected.
772   *
773   * @param string the string representation of a {@code double} value
774   * @return the floating point value represented by {@code string}, or {@code null} if {@code
775   *     string} has a length of zero or cannot be parsed as a {@code double} value
776   * @throws NullPointerException if {@code string} is {@code null}
777   * @since 14.0
778   */
779  @GwtIncompatible // regular expressions
780  public static @Nullable Double tryParse(String string) {
781    if (FLOATING_POINT_PATTERN.matcher(string).matches()) {
782      // TODO(lowasser): could be potentially optimized, but only with
783      // extensive testing
784      try {
785        return parseDouble(string);
786      } catch (NumberFormatException e) {
787        // Double.parseDouble has changed specs several times, so fall through
788        // gracefully
789      }
790    }
791    return null;
792  }
793}