001/*
002 * Units of Measurement API
003 * Copyright (c) 2014-2023, Jean-Marie Dautelle, Werner Keil, Otavio Santana.
004 *
005 * All rights reserved.
006 *
007 * Redistribution and use in source and binary forms, with or without modification,
008 * are permitted provided that the following conditions are met:
009 *
010 * 1. Redistributions of source code must retain the above copyright notice,
011 *    this list of conditions and the following disclaimer.
012 *
013 * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions
014 *    and the following disclaimer in the documentation and/or other materials provided with the distribution.
015 *
016 * 3. Neither the name of JSR-385 nor the names of its contributors may be used to endorse or promote products
017 *    derived from this software without specific prior written permission.
018 *
019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
020 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
021 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
022 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
023 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
024 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
025 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
026 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
027 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
028 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
029 */
030package javax.measure;
031
032/**
033 * Provides support for common binary prefixes to be used by units. For example:
034 * <pre>
035 * {@code import static systems.uom.unicode.CLDR.*;  // Static import (from Unicode System).
036 * import static javax.measure.BinaryPrefix.*; // Static import.
037 * import javax.measure.*;
038 * import systems.uom.quantity.Information; // (from Systems Quantities)
039 * ...
040 * Unit<Information> MEBIT  = MEBI(BIT);
041 * Unit<Information> GIBYTE = GIBI(BYTE);} 
042 * </pre>
043 * You could also apply <code>Unit.prefix</code>:
044 * <pre>
045 * {@code ...
046 * Unit<Information> MEBIT  = BIT.prefix(MEBI);
047 * Unit<Information> GIBYTE = BYTE.prefix(GIBI);}
048 * </pre>
049 * 
050 * <p>
051 * <b>Do not use ordinal() to obtain the numeric representation of BinaryPrefix. Use getValue() and getExponent() instead.</b>
052 * </p>
053 * 
054 * <dl>
055 * <dt><span class="strong">Implementation Requirements</span></dt><dd>This is an immutable and thread-safe enum.</dd>
056 * </dl> 
057 *
058 * @author <a href="mailto:werner@units.tech">Werner Keil</a>
059 * @version 2.2, May 20, 2023
060 * @see <a href="https://en.wikipedia.org/wiki/Binary_prefix">Wikipedia: Binary Prefix</a>
061 * @since 2.0
062 */
063public enum BinaryPrefix implements Prefix {
064    /** Prefix for 1024. */
065    KIBI("Ki", 1),
066    /** Prefix for 1024<sup>2</sup>. */
067    MEBI("Mi", 2),
068    /** Prefix for 1024<sup>3</sup>. */
069    GIBI("Gi", 3),
070    /** Prefix for 1024<sup>4</sup>. */
071    TEBI("Ti", 4),
072    /** Prefix for 1024<sup>5</sup>. */
073    PEBI("Pi", 5),
074    /** Prefix for 1024<sup>6</sup>. */
075    EXBI("Ei", 6),
076    /** Prefix for 1024<sup>7</sup>. */
077    ZEBI("Zi", 7),
078    /** Prefix for 1024<sup>8</sup>. */
079    YOBI("Yi", 8);
080
081    /**
082     * The symbol of this prefix, as returned by {@link #getSymbol}.
083     *
084     * @serial
085     * @see #getSymbol()
086     */
087    private final String symbol;
088
089    /**
090     * Exponent part of the associated factor in base^exponent representation.
091     */
092    private final int exponent;
093
094    /**
095     * Creates a new prefix.
096     *
097     * @param symbol
098     *          the symbol of this prefix.
099     * @param exponent
100     *          part of the associated factor in base^exponent representation.
101     */
102    private BinaryPrefix(String symbol, int exponent) {
103        this.symbol = symbol;
104        this.exponent = exponent;
105    }
106
107    /**
108     * Returns the specified unit multiplied by the factor <code>1024</code> (binary prefix).
109     *
110     * @param <Q>
111     *          type of the quantity measured by the unit.
112     * @param unit
113     *          any unit.
114     * @return <code>unit.multiply(1024)</code>.
115     */
116    public static <Q extends Quantity<Q>> Unit<Q> KIBI(Unit<Q> unit) {
117        return unit.prefix(KIBI);
118    }
119
120    /**
121     * Returns the specified unit multiplied by the factor <code>1024<sup>2</sup></code> (binary prefix).
122     *
123     * @param <Q>
124     *          type of the quantity measured by the unit.
125     * @param unit
126     *          any unit.
127     * @return <code>unit.multiply(1048576)</code>.
128     */
129    public static <Q extends Quantity<Q>> Unit<Q> MEBI(Unit<Q> unit) {
130        return unit.prefix(MEBI);
131    }
132
133    /**
134     * Returns the specified unit multiplied by the factor <code>1024<sup>3</sup></code> (binary prefix).
135     *
136     * @param <Q>
137     *          type of the quantity measured by the unit.
138     * @param unit
139     *          any unit.
140     * @return <code>unit.multiply(1073741824)</code>.
141     */
142    public static <Q extends Quantity<Q>> Unit<Q> GIBI(Unit<Q> unit) {
143        return unit.prefix(GIBI);
144    }
145
146    /**
147     * Returns the specified unit multiplied by the factor <code>1024<sup>4</sup></code> (binary prefix).
148     *
149     * @param <Q>
150     *          type of the quantity measured by the unit.
151     * @param unit
152     *          any unit.
153     * @return <code>unit.multiply(1099511627776L)</code>.
154     */
155    public static <Q extends Quantity<Q>> Unit<Q> TEBI(Unit<Q> unit) {
156        return unit.prefix(TEBI);
157    }
158
159    /**
160     * Returns the specified unit multiplied by the factor <code>1024<sup>5</sup></code> (binary prefix).
161     *
162     * @param <Q>
163     *          type of the quantity measured by the unit.
164     * @param unit
165     *          any unit.
166     * @return <code>unit.multiply(1125899906842624L)</code>.
167     */
168    public static <Q extends Quantity<Q>> Unit<Q> PEBI(Unit<Q> unit) {
169        return unit.prefix(PEBI);
170    }
171
172    /**
173     * Returns the specified unit multiplied by the factor <code>1024<sup>6</sup></code> (binary prefix).
174     *
175     * @param <Q>
176     *          type of the quantity measured by the unit.
177     * @param unit
178     *          any unit.
179     * @return <code>unit.multiply(1152921504606846976L)</code>.
180     */
181    public static <Q extends Quantity<Q>> Unit<Q> EXBI(Unit<Q> unit) {
182        return unit.prefix(EXBI);
183    }
184
185    /**
186     * Returns the specified unit multiplied by the factor <code>1024<sup>7</sup></code> (binary prefix).
187     *
188     * @param <Q>
189     *          type of the quantity measured by the unit.
190     * @param unit
191     *          any unit.
192     * @return <code>unit.multiply(1152921504606846976d)</code>.
193     */
194    public static <Q extends Quantity<Q>> Unit<Q> ZEBI(Unit<Q> unit) {
195        return unit.prefix(ZEBI);
196    }
197
198    /**
199     * Returns the specified unit multiplied by the factor <code>1024<sup>8</sup></code> (binary prefix).
200     *
201     * @param <Q>
202     *          type of the quantity measured by the unit.
203     * @param unit
204     *          any unit.
205     * @return <code>unit.multiply(1208925819614629174706176d)</code>.
206     */
207    public static <Q extends Quantity<Q>> Unit<Q> YOBI(Unit<Q> unit) {
208        return unit.prefix(YOBI);
209    }
210
211    /**
212     * Returns the symbol of this prefix.
213     *
214     * @return this prefix symbol, not {@code null}.
215     */
216    @Override
217    public String getSymbol() {
218        return symbol;
219    }
220
221    /**
222     * Base part of the associated factor in {@code base^exponent} representation. For binary prefix, this is always 1024.
223     */
224    @Override
225    public Integer getValue() {
226        return 1024;
227    }
228
229    /**
230     * Exponent part of the associated factor in {@code base^exponent} representation.
231     */
232    @Override
233    public int getExponent() {
234        return exponent;
235    }
236
237    /**
238     * Returns the name of this prefix.
239     *
240     * @return this prefix name, not {@code null}.
241     */
242    @Override
243    public String getName() {
244        return name();
245    }
246}