001/*
002 * The MIT License (MIT)
003 *
004 * Copyright (c) 2015-2023 decimal4j (tools4j), Marco Terzer
005 *
006 * Permission is hereby granted, free of charge, to any person obtaining a copy
007 * of this software and associated documentation files (the "Software"), to deal
008 * in the Software without restriction, including without limitation the rights
009 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
010 * copies of the Software, and to permit persons to whom the Software is
011 * furnished to do so, subject to the following conditions:
012 *
013 * The above copyright notice and this permission notice shall be included in all
014 * copies or substantial portions of the Software.
015 *
016 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
017 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
018 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
019 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
020 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
021 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
022 * SOFTWARE.
023 */
024package org.decimal4j.scale;
025
026import java.util.Arrays;
027import java.util.Collections;
028import java.util.List;
029
030import org.decimal4j.scale.Scale10f;
031import org.decimal4j.scale.Scale11f;
032import org.decimal4j.scale.Scale12f;
033import org.decimal4j.scale.Scale13f;
034import org.decimal4j.scale.Scale14f;
035import org.decimal4j.scale.Scale15f;
036import org.decimal4j.scale.Scale16f;
037import org.decimal4j.scale.Scale17f;
038import org.decimal4j.scale.Scale18f;
039import org.decimal4j.scale.Scale1f;
040import org.decimal4j.scale.Scale2f;
041import org.decimal4j.scale.Scale3f;
042import org.decimal4j.scale.Scale4f;
043import org.decimal4j.scale.Scale5f;
044import org.decimal4j.scale.Scale6f;
045import org.decimal4j.scale.Scale7f;
046import org.decimal4j.scale.Scale8f;
047import org.decimal4j.scale.Scale9f;
048
049/**
050 * Utility class with static members to access {@link ScaleMetrics} instances.
051 */
052public final class Scales {
053
054        //@formatter:off
055        private static final ScaleMetrics[] SCALES = {
056                Scale0f.INSTANCE,
057                Scale1f.INSTANCE,
058                Scale2f.INSTANCE,
059                Scale3f.INSTANCE,
060                Scale4f.INSTANCE,
061                Scale5f.INSTANCE,
062                Scale6f.INSTANCE,
063                Scale7f.INSTANCE,
064                Scale8f.INSTANCE,
065                Scale9f.INSTANCE,
066                Scale10f.INSTANCE,
067                Scale11f.INSTANCE,
068                Scale12f.INSTANCE,
069                Scale13f.INSTANCE,
070                Scale14f.INSTANCE,
071                Scale15f.INSTANCE,
072                Scale16f.INSTANCE,
073                Scale17f.INSTANCE,
074                Scale18f.INSTANCE
075        };
076        //@formatter:on
077
078        /**
079         * All scale metric constants in an immutable ordered list:
080         * <br>
081         * {@code VALUES=[Scale0f.INSTANCE, Scale1f.INSTANCE, ..., Scale18f.INSTANCE]}
082         */
083        public static final List<ScaleMetrics> VALUES = Collections.unmodifiableList(Arrays.asList(SCALES));
084        
085        /**
086         * The minimum scale that can be passed to {@link #getScaleMetrics(int)} without causing an
087         * exception; the minimum scale is 0.
088         */
089        public static final int MIN_SCALE = 0;
090
091        /**
092         * The maximum scale that can be passed to {@link #getScaleMetrics(int)} without causing an
093         * exception; the maximum scale is 18.
094         */
095        public static final int MAX_SCALE = 18;
096
097        //@formatter:off
098        private static final long[] SCALE_FACTORS = {
099                1, 
100                10, 
101                100, 
102                1000, 
103                10000, 
104                100000, 
105                1000000, 
106                10000000, 
107                100000000, 
108                1000000000, 
109                10000000000L, 
110                100000000000L, 
111                1000000000000L, 
112                10000000000000L, 
113                100000000000000L, 
114                1000000000000000L, 
115                10000000000000000L, 
116                100000000000000000L, 
117                1000000000000000000L 
118        };
119        //@formatter:on
120
121        /**
122         * Returns the {@code ScaleMetrics} constant based on a given scale
123         * 
124         * @param scale
125         *            the scale value; must be in {@code [0,18]} both ends inclusive
126         * @return the scale metrics constant corresponding to {@code scale}
127         * @throws IllegalArgumentException
128         *             if scale is not in {@code [0, 18]}
129         * @see #MIN_SCALE
130         * @see #MAX_SCALE
131         */
132        public static final ScaleMetrics getScaleMetrics(int scale) {
133                if (MIN_SCALE <= scale & scale <= MAX_SCALE) {
134                        return SCALES[scale];
135                }
136                throw new IllegalArgumentException("illegal scale, must be in ["+ MIN_SCALE + "," + MAX_SCALE + "] but was: " + scale);
137        }
138
139        /**
140         * Returns the {@code ScaleMetrics} constant that matches the given
141         * {@code scaleFactor} if any and null otherwise.
142         * 
143         * @param scaleFactor
144         *            the scale factor to find
145         * @return the scale metrics constant with
146         *         {@link ScaleMetrics#getScaleFactor()} equal to
147         *         {@code scaleFactor} if it exists and null otherwise
148         * @see ScaleMetrics#getScaleFactor()
149         */
150        public static final ScaleMetrics findByScaleFactor(long scaleFactor) {
151                final int index = Arrays.binarySearch(SCALE_FACTORS, scaleFactor);
152                return index < 0 ? null : VALUES.get(index);
153        }
154
155        //no instances
156        private Scales() {
157                super();
158        }
159}