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 }