kinow commented on a change in pull request #248:
URL: https://github.com/apache/commons-text/pull/248#discussion_r671751769



##########
File path: src/main/java/org/apache/commons/text/numbers/DoubleFormat.java
##########
@@ -0,0 +1,736 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.text.numbers;
+
+import java.text.DecimalFormatSymbols;
+import java.util.Objects;
+import java.util.function.DoubleFunction;
+import java.util.function.Function;
+
+/** Enum containing standard double format types with methods to produce
+ * configured formatter instances. This type is intended to provide a
+ * quick and convenient way to create lightweight, thread-safe double format 
functions
+ * for common format types using a builder pattern. Output can be localized by
+ * passing a {@link DecimalFormatSymbols} instance to the
+ * {@link Builder#formatSymbols(DecimalFormatSymbols) formatSymbols} method or 
by
+ * directly calling the various other builder configuration methods, such as
+ * {@link Builder#digits(String) digits}.
+ *
+ * <p><strong>Comparison with DecimalFormat</strong>
+ * <p>This type provides some of the same functionality as Java's own
+ * {@link java.text.DecimalFormat}. However, unlike {@code DecimalFormat}, the 
format
+ * functions produced by this type are lightweight and thread-safe, making them
+ * much easier to work with in multi-threaded environments. They also provide 
performance
+ * comparable to, and in many cases faster than, {@code DecimalFormat}.
+ *
+ * <p><strong>Examples</strong>
+ * <pre>
+ * // construct a formatter equivalent to Double.toString()
+ * DoubleFunction&lt;String&gt; fmt = DoubleFormat.MIXED.builder().build();
+ *
+ * // construct a formatter equivalent to Double.toString() but using
+ * // format symbols for a specific locale
+ * DoubleFunction&lt;String&gt; fmt = DoubleFormat.MIXED.builder()
+ *      .formatSymbols(DecimalFormatSymbols.getInstance(locale))
+ *      .build();
+ *
+ * // construct a formatter equivalent to the DecimalFormat pattern "0.0##"
+ * DoubleFunction&lt;String&gt; fmt = DoubleFormat.PLAIN.builder()
+ *      .minDecimalExponent(-3)
+ *      .build();
+ *
+ * // construct a formatter equivalent to the DecimalFormat pattern 
"#,##0.0##",
+ * // where whole number groups of thousands are separated
+ * DoubleFunction&lt;String&gt; fmt = DoubleFormat.PLAIN.builder()
+ *      .minDecimalExponent(-3)
+ *      .groupThousands(true)
+ *      .build();
+ *
+ * // construct a formatter equivalent to the DecimalFormat pattern "0.0##E0"
+ * DoubleFunction&lt;String&gt; fmt = DoubleFormat.SCIENTIFIC.builder()
+ *      .maxPrecision(4)
+ *      .alwaysIncludeExponent(true)
+ *      .build()
+ *
+ * // construct a formatter equivalent to the DecimalFormat pattern 
"##0.0##E0",
+ * // i.e. "engineering format"
+ * DoubleFunction&lt;String&gt; fmt = DoubleFormat.ENGINEERING.builder()
+ *      .maxPrecision(6)
+ *      .alwaysIncludeExponent(true)
+ *      .build()
+ * </pre>
+ *
+ * <p><strong>Implementation Notes</strong>
+ * <p>{@link java.math.RoundingMode#HALF_EVEN Half-even} rounding is used in 
cases where the
+ * decimal value must be rounded in order to meet the configuration 
requirements of the formatter
+ * instance.
+ */
+public enum DoubleFormat {
+
+    /** Number format without exponents.
+     * Ex:
+     * <pre>
+     * 0.0
+     * 12.401
+     * 100000.0
+     * 1450000000.0
+     * 0.0000000000123
+     * </pre>
+     */
+    PLAIN(PlainDoubleFormat::new),
+
+    /** Number format that uses exponents and contains a single digit
+     * to the left of the decimal point.
+     * Ex:
+     * <pre>
+     * 0.0
+     * 1.2401E1
+     * 1.0E5
+     * 1.45E9
+     * 1.23E-11
+     * </pre>
+     */
+    SCIENTIFIC(ScientificDoubleFormat::new),
+
+    /** Number format similar to {@link #SCIENTIFIC scientific format} but 
adjusted
+     * so that the exponent value is always a multiple of 3, allowing easier 
alignment
+     * with SI prefixes.
+     * Ex:
+     * <pre>
+     * 0.0
+     * 12.401
+     * 100.0E3
+     * 1.45E9
+     * 12.3E-12
+     * </pre>
+     */
+    ENGINEERING(EngineeringDoubleFormat::new),
+
+    /** Number format that uses {@link #PLAIN plain format} for small numbers 
and
+     * {@link #SCIENTIFIC scientific format} for large numbers. The number 
thresholds
+     * can be configured through the
+     * {@link Builder#plainFormatMinDecimalExponent 
plainFormatMinDecimalExponent}
+     * and
+     * {@link Builder#plainFormatMaxDecimalExponent 
plainFormatMaxDecimalExponent}
+     * properties.
+     * Ex:
+     * <pre>
+     * 0.0
+     * 12.401
+     * 100000.0
+     * 1.45E9
+     * 1.23E-11
+     * </pre>
+     */
+    MIXED(MixedDoubleFormat::new);
+
+    /** Function used to construct instances for this format type. */
+    private final Function<Builder, DoubleFunction<String>> factory;
+
+    /** Construct a new instance.
+     * @param factory function used to construct format instances
+     */
+    DoubleFormat(final Function<Builder, DoubleFunction<String>> factory) {
+        this.factory = factory;
+    }
+
+    /** Return a {@link Builder} for constructing formatter functions for this 
format type.
+     * @return builder instance
+     */
+    public Builder builder() {
+        return new Builder(factory);
+    }
+
+    /** Class for constructing configured format functions for standard double 
format types.
+     */
+    public static final class Builder {
+
+        /** Default value for the plain format max decimal exponent. */
+        private static final int DEFAULT_PLAIN_FORMAT_MAX_DECIMAL_EXPONENT = 6;
+
+        /** Default value for the plain format min decimal exponent. */
+        private static final int DEFAULT_PLAIN_FORMAT_MIN_DECIMAL_EXPONENT = 
-3;
+
+        /** Default decimal digit characters. */
+        private static final String DEFAULT_DECIMAL_DIGITS = "0123456789";
+
+        /** Function used to construct format instances. */
+        private final Function<Builder, DoubleFunction<String>> factory;
+
+        /** Maximum number of significant decimal digits in formatted strings. 
*/
+        private int maxPrecision = 0;
+
+        /** Minimum decimal exponent. */
+        private int minDecimalExponent = Integer.MIN_VALUE;
+
+        /** Max decimal exponent to use with plain formatting with the mixed 
format type. */
+        private int plainFormatMaxDecimalExponent = 
DEFAULT_PLAIN_FORMAT_MAX_DECIMAL_EXPONENT;
+
+        /** Min decimal exponent to use with plain formatting with the mixed 
format type. */
+        private int plainFormatMinDecimalExponent = 
DEFAULT_PLAIN_FORMAT_MIN_DECIMAL_EXPONENT;
+
+        /** String representing infinity. */
+        private String infinity = "Infinity";
+
+        /** String representing NaN. */
+        private String nan = "NaN";
+
+        /** Flag determining if fraction placeholders should be used. */
+        private boolean fractionPlaceholder = true;
+
+        /** Flag determining if signed zero strings are allowed. */
+        private boolean signedZero = true;
+
+        /** String of digit characters 0-9. */
+        private String digits = DEFAULT_DECIMAL_DIGITS;
+
+        /** Decimal separator character. */
+        private char decimalSeparator = '.';
+
+        /** Character used to separate groups of thousands. */
+        private char groupingSeparator = ',';
+
+        /** If true, thousands groups will be separated by the grouping 
separator. */
+        private boolean groupThousands = false;
+
+        /** Minus sign character. */
+        private char minusSign = '-';
+
+        /** Exponent separator character. */
+        private String exponentSeparator = "E";
+
+        /** Flag indicating if the exponent value should always be included, 
even if zero. */
+        private boolean alwaysIncludeExponent = false;

Review comment:
       Fair enough @darkma773r. The API is easy to understand, and the 
documentation is great too. So let's go with the current design and see if we 
get feedback from other devs and/or users.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


Reply via email to