View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.numbers.core;
18  
19  import org.apache.commons.rng.UniformRandomProvider;
20  
21  /** Class providing test utilities related to doubles.
22   */
23  final class DoubleTestUtils {
24  
25      /** Utility class; no instantiation. */
26      private DoubleTestUtils() {}
27  
28      /** Compute the difference in ULP between two arguments of the same sign.
29       * @param a first argument
30       * @param b second argument
31       * @return ULP difference between the arguments
32       */
33      public static int computeUlpDifference(final double a, final double b) {
34          return (int) (Double.doubleToLongBits(a) - Double.doubleToLongBits(b));
35      }
36  
37      /** Construct an array of length {@code len} containing random double values with exponents between
38       * {@code minExp} and {@code maxExp}.
39       * @param len vector length
40       * @param minExp minimum element exponent value
41       * @param maxExp maximum element exponent value
42       * @param rng random number generator
43       * @return random vector array
44       */
45      public static double[] randomArray(final int len, final int minExp, final int maxExp,
46              final UniformRandomProvider rng) {
47          final double[] v = new double[len];
48          for (int i = 0; i < v.length; ++i) {
49              v[i] = randomDouble(minExp, maxExp, rng);
50          }
51          return v;
52      }
53  
54      /** Construct a random double with an exponent in the range {@code [minExp, maxExp]}.
55       * @param minExp minimum exponent; must be less than {@code maxExp}
56       * @param maxExp maximum exponent; must be greater than {@code minExp}
57       * @param rng random number generator
58       * @return random double value with an exponent in the specified range
59       */
60      public static double randomDouble(final int minExp, final int maxExp, final UniformRandomProvider rng) {
61          // Create random doubles using random bits in the sign bit and the mantissa.
62          final long mask = ((1L << 52) - 1) | 1L << 63;
63          final long bits = rng.nextLong() & mask;
64          // The exponent must be unsigned so + 1023 to the signed exponent
65          final int expRange = maxExp - minExp + 1;
66          final long exp = rng.nextInt(expRange) + minExp + 1023;
67          return Double.longBitsToDouble(bits | (exp << 52));
68      }
69  }