001 /*
002 * Java Genetic Algorithm Library (jenetics-7.1.1).
003 * Copyright (c) 2007-2022 Franz Wilhelmstötter
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 *
017 * Author:
018 * Franz Wilhelmstötter (franz.wilhelmstoetter@gmail.com)
019 */
020 package io.jenetics.prog.op;
021
022 import static java.util.Objects.requireNonNull;
023
024 import java.util.Optional;
025 import java.util.regex.Pattern;
026
027 /**
028 * @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a>
029 * @version 4.4
030 * @since 4.4
031 */
032 final class Numbers {
033 private Numbers() {}
034
035 // Regex for checking if parsable as double as described in
036 // Double.valueOf Java documentation.
037
038 private static final String DIGITS = "(\\p{Digit}+)";
039
040 private static final String HEX_DIGITS = "(\\p{XDigit}+)";
041
042 // an exponent is 'e' or 'E' followed by an optionally
043 // signed decimal integer.
044 private static final String EXP = "[eE][+-]?"+ DIGITS;
045
046 private static final String FP_REGEX =
047 "[\\x00-\\x20]*"+ // Optional leading "whitespace"
048 "[+-]?(" + // Optional sign character
049 "NaN|" + // "NaN" string
050 "Infinity|" + // "Infinity" string
051
052 // A decimal floating-point string representing a finite positive
053 // number without a leading sign has at most five basic pieces:
054 // Digits . Digits ExponentPart FloatTypeSuffix
055 //
056 // Since this method allows integer-only strings as input
057 // in addition to strings of floating-point literals, the
058 // two sub-patterns below are simplifications of the grammar
059 // productions from section 3.10.2 of
060 // The Java Language Specification.
061
062 // Digits ._opt Digits_opt ExponentPart_opt FloatTypeSuffix_opt
063 "((("+ DIGITS +"(\\.)?("+ DIGITS +"?)("+ EXP +")?)|"+
064
065 // . Digits ExponentPart_opt FloatTypeSuffix_opt
066 "(\\.("+ DIGITS +")("+ EXP +")?)|"+
067
068 // Hexadecimal strings
069 "((" +
070 // 0[xX] HexDigits ._opt BinaryExponent FloatTypeSuffix_opt
071 "(0[xX]" + HEX_DIGITS + "(\\.)?)|" +
072
073 // 0[xX] HexDigits_opt . HexDigits BinaryExponent FloatTypeSuffix_opt
074 "(0[xX]" + HEX_DIGITS + "?(\\.)" + HEX_DIGITS + ")" +
075
076 ")[pP][+-]?" + DIGITS + "))" +
077 "[fFdD]?))" +
078 "[\\x00-\\x20]*";// Optional trailing "whitespace"
079
080 private static final Pattern FP_PATTERN = Pattern.compile(FP_REGEX);
081
082 static boolean isNumber(final String value) {
083 requireNonNull(value);
084 return FP_PATTERN.matcher(value).matches();
085 }
086
087 static Optional<Double> toDoubleOptional(final String value) {
088 return isNumber(value)
089 ? Optional.of(Double.parseDouble(value))
090 : Optional.empty();
091 }
092
093 static Double[] box(final double... values) {
094 final Double[] result = new Double[values.length];
095 for (int i = values.length; --i >= 0;) {
096 result[i] = values[i];
097 }
098 return result;
099 }
100
101 }
|