001/*
002 * The MIT License (MIT)
003 *
004 * Copyright (c) 2015-2024 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.immutable;
025
026import java.math.BigDecimal;
027import java.math.BigInteger;
028import java.math.RoundingMode;
029
030import org.decimal4j.api.Decimal;
031import org.decimal4j.api.DecimalArithmetic;
032import org.decimal4j.base.AbstractImmutableDecimal;
033import org.decimal4j.exact.Multipliable9f;
034import org.decimal4j.factory.Factory9f;
035import org.decimal4j.mutable.MutableDecimal9f;
036import org.decimal4j.scale.Scale9f;
037
038/**
039 * <code>Decimal9f</code> represents an immutable decimal number with a fixed
040 * number of 9 digits to the right of the decimal point.
041 * <p>
042 * All methods for this class throw {@code NullPointerException} when passed a
043 * {@code null} object reference for any input parameter.
044 */
045public final class Decimal9f extends AbstractImmutableDecimal<Scale9f, Decimal9f> {
046
047        private static final long serialVersionUID = 1L;
048
049        /** Scale value 9 for {@code Decimal9f} returned by {@link #getScale()}.*/
050        public static final int SCALE = 9;
051
052        /** Scale metrics constant for {@code Decimal9f} returned by {@link #getScaleMetrics()}.*/
053        public static final Scale9f METRICS = Scale9f.INSTANCE;
054
055        /** Factory constant for {@code Decimal9f} returned by {@link #getFactory()}.*/
056        public static final Factory9f FACTORY = Factory9f.INSTANCE;
057        
058        /**
059         * Default arithmetic for {@code Decimal9f} performing unchecked operations with rounding mode 
060         * {@link RoundingMode#HALF_UP HALF_UP}.
061         */
062        public static final DecimalArithmetic DEFAULT_ARITHMETIC = METRICS.getDefaultArithmetic();
063        
064        /**
065         * Default arithmetic for {@code Decimal9f} performing checked operations with rounding mode 
066         * {@link RoundingMode#HALF_UP HALF_UP}.
067         */
068        public static final DecimalArithmetic DEFAULT_CHECKED_ARITHMETIC = METRICS.getDefaultCheckedArithmetic();
069
070        /** The unscaled long value that represents one.*/
071        public static final long ONE_UNSCALED = METRICS.getScaleFactor();
072
073        /** The {@code Decimal9f} constant zero.*/
074        public static final Decimal9f ZERO = new Decimal9f(0);
075    /**
076     * A constant holding the smallest positive value a {@code Decimal9f}
077     * can have, 10<sup>-9</sup>.
078     */
079        public static final Decimal9f ULP = new Decimal9f(1);
080
081    /**
082     * Initialize static constant array when class is loaded.
083     */
084    private static final int MAX_CONSTANT = 10;
085    private static final Decimal9f POS_CONST[] = new Decimal9f[MAX_CONSTANT+1];
086    private static final Decimal9f NEG_CONST[] = new Decimal9f[MAX_CONSTANT+1];
087
088    static {
089        for (int i = 1; i <= MAX_CONSTANT; i++) {
090            POS_CONST[i] = new Decimal9f(ONE_UNSCALED * i);
091            NEG_CONST[i] = new Decimal9f(-ONE_UNSCALED * i);
092        }
093    }
094
095        /** The {@code Decimal9f} constant 1.*/
096        public static final Decimal9f ONE = valueOf(1);
097        /** The {@code Decimal9f} constant 2.*/
098        public static final Decimal9f TWO = valueOf(2);
099        /** The {@code Decimal9f} constant 3.*/
100        public static final Decimal9f THREE = valueOf(3);
101        /** The {@code Decimal9f} constant 4.*/
102        public static final Decimal9f FOUR = valueOf(4);
103        /** The {@code Decimal9f} constant 5.*/
104        public static final Decimal9f FIVE = valueOf(5);
105        /** The {@code Decimal9f} constant 6.*/
106        public static final Decimal9f SIX = valueOf(6);
107        /** The {@code Decimal9f} constant 7.*/
108        public static final Decimal9f SEVEN = valueOf(7);
109        /** The {@code Decimal9f} constant 8.*/
110        public static final Decimal9f EIGHT = valueOf(8);
111        /** The {@code Decimal9f} constant 9.*/
112        public static final Decimal9f NINE = valueOf(9);
113        /** The {@code Decimal9f} constant 10.*/
114        public static final Decimal9f TEN = valueOf(10);
115        /** The {@code Decimal9f} constant 100.*/
116        public static final Decimal9f HUNDRED = new Decimal9f(100 * ONE_UNSCALED);
117        /** The {@code Decimal9f} constant 1000.*/
118        public static final Decimal9f THOUSAND = new Decimal9f(1000 * ONE_UNSCALED);
119        /** The {@code Decimal9f} constant 10<sup>6</sup>.*/
120        public static final Decimal9f MILLION = new Decimal9f(1000000 * ONE_UNSCALED);
121        /** The {@code Decimal9f} constant 10<sup>9</sup>.*/
122        public static final Decimal9f BILLION = new Decimal9f(1000000000 * ONE_UNSCALED);
123
124        /** The {@code Decimal9f} constant -1.*/
125        public static final Decimal9f MINUS_ONE = valueOf(-1);
126
127        /** The {@code Decimal9f} constant 0.5.*/
128        public static final Decimal9f HALF = new Decimal9f(ONE_UNSCALED / 2);
129        /** The {@code Decimal9f} constant 0.1.*/
130        public static final Decimal9f TENTH = new Decimal9f(ONE_UNSCALED / 10);
131        /** The {@code Decimal9f} constant 0.01.*/
132        public static final Decimal9f HUNDREDTH = new Decimal9f(ONE_UNSCALED / 100);
133        /** The {@code Decimal9f} constant 0.001.*/
134        public static final Decimal9f THOUSANDTH = new Decimal9f(ONE_UNSCALED / 1000);
135        /** The {@code Decimal9f} constant 10<sup>-6</sup>.*/
136        public static final Decimal9f MILLIONTH = new Decimal9f(ONE_UNSCALED / 1000000);
137        /** The {@code Decimal9f} constant 10<sup>-9</sup>.*/
138        public static final Decimal9f BILLIONTH = new Decimal9f(ONE_UNSCALED / 1000000000);
139
140    /**
141     * A constant holding the maximum value a {@code Decimal9f} can have,
142     * 9223372036.854775807.
143     */
144        public static final Decimal9f MAX_VALUE = new Decimal9f(Long.MAX_VALUE);
145    /**
146     * A constant holding the maximum integer value a {@code Decimal9f}
147     * can have, 9223372036.000000000.
148     */
149        public static final Decimal9f MAX_INTEGER_VALUE = new Decimal9f((Long.MAX_VALUE / ONE_UNSCALED) * ONE_UNSCALED);
150    /**
151     * A constant holding the minimum value a {@code Decimal9f} can have,
152     * -9223372036.854775808.
153     */
154        public static final Decimal9f MIN_VALUE = new Decimal9f(Long.MIN_VALUE);
155    /**
156     * A constant holding the minimum integer value a {@code Decimal9f}
157     * can have, -9223372036.000000000.
158     */
159        public static final Decimal9f MIN_INTEGER_VALUE = new Decimal9f((Long.MIN_VALUE / ONE_UNSCALED) * ONE_UNSCALED);
160
161        /**
162         * Private constructor with unscaled value.
163         *
164         * @param unscaled the unscaled value
165         */
166        private Decimal9f(long unscaled) {
167                super(unscaled);
168        }
169
170        /**
171         * Translates the string representation of a {@code Decimal} into a
172         * {@code Decimal9f}. The string representation consists of an
173         * optional sign, {@code '+'} or {@code '-'} , followed by a sequence of
174         * zero or more decimal digits ("the integer"), optionally followed by a
175         * fraction.
176         * <p>
177         * The fraction consists of a decimal point followed by zero or more decimal
178         * digits. The string must contain at least one digit in either the integer
179         * or the fraction. If the fraction contains more than 9 digits, the 
180         * value is rounded using {@link RoundingMode#HALF_UP HALF_UP} rounding. An 
181         * exception is thrown if the value is too large to be represented as a 
182         * {@code Decimal9f}.
183         *
184         * @param value
185         *            String value to convert into a {@code Decimal9f}
186         * @throws NumberFormatException
187         *             if {@code value} does not represent a valid {@code Decimal}
188         *             or if the value is too large to be represented as a 
189         *             {@code Decimal9f}
190         */
191        public Decimal9f(String value) {
192                super(DEFAULT_CHECKED_ARITHMETIC.parse(value));
193        }
194        
195        @Override
196        public final Scale9f getScaleMetrics() {
197                return METRICS;
198        }
199
200        @Override
201        public final int getScale() {
202                return SCALE;
203        }
204
205        @Override
206        public final Factory9f getFactory() {
207                return FACTORY;
208        }
209
210        @Override
211        protected final Decimal9f self() {
212                return this;
213        }
214
215        @Override
216        protected final DecimalArithmetic getDefaultArithmetic() {
217                return DEFAULT_ARITHMETIC;
218        }
219        
220        @Override
221        protected final DecimalArithmetic getDefaultCheckedArithmetic() {
222                return DEFAULT_CHECKED_ARITHMETIC;
223        }
224        
225        @Override
226        protected final DecimalArithmetic getRoundingDownArithmetic() {
227                return METRICS.getRoundingDownArithmetic();
228        }
229        
230        @Override
231        protected final DecimalArithmetic getRoundingFloorArithmetic() {
232                return METRICS.getRoundingFloorArithmetic();
233        }
234        
235        @Override
236        protected final DecimalArithmetic getRoundingHalfEvenArithmetic() {
237                return METRICS.getRoundingHalfEvenArithmetic();
238        }
239        
240        @Override
241        protected final DecimalArithmetic getRoundingUnnecessaryArithmetic() {
242                return METRICS.getRoundingUnnecessaryArithmetic();
243        }
244
245        /**
246         * Returns a {@code Decimal9f} whose value is numerically equal to
247         * that of the specified {@code long} value. An exception is thrown if the
248         * specified value is too large to be represented as a {@code Decimal9f}.
249         *
250         * @param value
251         *            long value to convert into a {@code Decimal9f}
252         * @return a {@code Decimal9f} value numerically equal to the specified 
253         *            {@code long} value
254         * @throws IllegalArgumentException
255         *            if {@code value} is too large to be represented as a 
256         *            {@code Decimal9f}
257         */
258        public static Decimal9f valueOf(long value) {
259        if (value == 0)
260            return ZERO;
261        if (value > 0 & value <= MAX_CONSTANT)
262            return POS_CONST[(int) value];
263        else if (value < 0 & value >= -MAX_CONSTANT)
264            return NEG_CONST[(int) -value];
265                return valueOfUnscaled(DEFAULT_CHECKED_ARITHMETIC.fromLong(value));
266        }
267
268        /**
269         * Returns a {@code Decimal9f} whose value is calculated by
270         * rounding the specified {@code float} argument to scale 9
271         * using {@link RoundingMode#HALF_UP HALF_UP} rounding. An exception is thrown
272         * if the specified value is too large to be represented as a {@code Decimal9f}. 
273         *
274         * @param value
275         *            float value to convert into a {@code Decimal9f}
276         * @return a {@code Decimal9f} calculated as: <code>round<sub>HALF_UP</sub>(value)</code>
277         * @throws IllegalArgumentException
278         *             if {@code value} is NaN or infinite or if the magnitude is
279         *             too large for the float to be represented as a {@code Decimal9f}
280         */
281        public static Decimal9f valueOf(float value) {
282                return valueOfUnscaled(DEFAULT_CHECKED_ARITHMETIC.fromFloat(value));
283        }
284
285        /**
286         * Returns a {@code Decimal9f} whose value is calculated by
287         * rounding the specified {@code float} argument to scale 9
288         * using the specified {@code roundingMode}. An exception is thrown
289         * if the specified value is too large to be represented as a {@code Decimal9f}. 
290         *
291         * @param value
292         *            float value to convert into a {@code Decimal9f}
293         * @param roundingMode
294         *            the rounding mode to apply during the conversion if necessary
295         * @return a {@code Decimal9f} calculated as: <code>round(value)</code>
296         * @throws IllegalArgumentException
297         *             if {@code value} is NaN or infinite or if the magnitude is
298         *             too large for the float to be represented as a {@code Decimal9f}
299         * @throws ArithmeticException
300         *             if {@code roundingMode==UNNECESSARY} and rounding is
301         *             necessary
302         */
303        public static Decimal9f valueOf(float value, RoundingMode roundingMode) {
304                return valueOfUnscaled(METRICS.getCheckedArithmetic(roundingMode).fromFloat(value));
305        }
306
307        /**
308         * Returns a {@code Decimal9f} whose value is calculated by
309         * rounding the specified {@code double} argument to scale 9
310         * using {@link RoundingMode#HALF_UP HALF_UP} rounding. An exception is thrown
311         * if the specified value is too large to be represented as a {@code Decimal9f}. 
312         *
313         * @param value
314         *            double value to convert into a {@code Decimal9f}
315         * @return a {@code Decimal9f} calculated as: <code>round<sub>HALF_UP</sub>(value)</code>
316         * @throws IllegalArgumentException
317         *             if {@code value} is NaN or infinite or if the magnitude is
318         *             too large for the double to be represented as a {@code Decimal9f}
319         */
320        public static Decimal9f valueOf(double value) {
321                return valueOfUnscaled(DEFAULT_CHECKED_ARITHMETIC.fromDouble(value));
322        }
323
324        /**
325         * Returns a {@code Decimal9f} whose value is calculated by
326         * rounding the specified {@code double} argument to scale 9
327         * using the specified {@code roundingMode}. An exception is thrown
328         * if the specified value is too large to be represented as a {@code Decimal9f}. 
329         *
330         * @param value
331         *            double value to convert into a {@code Decimal9f}
332         * @param roundingMode
333         *            the rounding mode to apply during the conversion if necessary
334         * @return a {@code Decimal9f} calculated as: <code>round(value)</code>
335         * @throws IllegalArgumentException
336         *             if {@code value} is NaN or infinite or if the magnitude is
337         *             too large for the double to be represented as a {@code Decimal9f}
338         * @throws ArithmeticException
339         *             if {@code roundingMode==UNNECESSARY} and rounding is
340         *             necessary
341         */
342        public static Decimal9f valueOf(double value, RoundingMode roundingMode) {
343                return valueOfUnscaled(METRICS.getCheckedArithmetic(roundingMode).fromDouble(value));
344        }
345
346        /**
347         * Returns a {@code Decimal9f} whose value is numerically equal to that of
348         * the specified {@link BigInteger} value. An exception is thrown if the
349         * specified value is too large to be represented as a {@code Decimal9f}.
350         *
351         * @param value
352         *            {@code BigInteger} value to convert into a {@code Decimal9f}
353         * @return a {@code Decimal9f} value numerically equal to the specified big 
354         *         integer value
355         * @throws IllegalArgumentException
356         *             if {@code value} is too large to be represented as a {@code Decimal9f}
357         */
358        public static Decimal9f valueOf(BigInteger value) {
359                return valueOfUnscaled(DEFAULT_CHECKED_ARITHMETIC.fromBigInteger(value));
360        }
361
362        /**
363         * Returns a {@code Decimal9f} whose value is calculated by rounding
364         * the specified {@link BigDecimal} argument to scale 9 using
365         * {@link RoundingMode#HALF_UP HALF_UP} rounding. An exception is thrown if the 
366         * specified value is too large to be represented as a {@code Decimal9f}.
367         *
368         * @param value
369         *            {@code BigDecimal} value to convert into a {@code Decimal9f}
370         * @return a {@code Decimal9f} calculated as: <code>round<sub>HALF_UP</sub>(value)</code>
371         * @throws IllegalArgumentException
372         *             if {@code value} is too large to be represented as a {@code Decimal9f}
373         */
374        public static Decimal9f valueOf(BigDecimal value) {
375                return valueOfUnscaled(DEFAULT_CHECKED_ARITHMETIC.fromBigDecimal(value));
376        }
377
378        /**
379         * Returns a {@code Decimal9f} whose value is calculated by rounding
380         * the specified {@link BigDecimal} argument to scale 9 using 
381         * the specified {@code roundingMode}. An exception is thrown if the 
382         * specified value is too large to be represented as a {@code Decimal9f}.
383         *
384         * @param value
385         *            {@code BigDecimal} value to convert into a {@code Decimal9f}
386         * @param roundingMode
387         *            the rounding mode to apply during the conversion if necessary
388         * @return a {@code Decimal9f} calculated as: <code>round(value)</code>
389         * @throws IllegalArgumentException
390         *             if {@code value} is too large to be represented as a {@code Decimal9f}
391         * @throws ArithmeticException
392         *             if {@code roundingMode==UNNECESSARY} and rounding is
393         *             necessary
394         */
395        public static Decimal9f valueOf(BigDecimal value, RoundingMode roundingMode) {
396                return valueOfUnscaled(METRICS.getCheckedArithmetic(roundingMode).fromBigDecimal(value));
397        }
398
399        /**
400         * Returns a {@code Decimal9f} whose value is calculated by rounding
401         * the specified {@link Decimal} argument to scale 9 using
402         * {@link RoundingMode#HALF_UP HALF_UP} rounding. An exception is thrown if the
403         * specified value is too large to be represented as a {@code Decimal9f}. 
404         *
405         * @param value
406         *            Decimal value to convert into a {@code Decimal9f} 
407         * @return a {@code Decimal9f} calculated as: <code>round<sub>HALF_UP</sub>(value)</code>
408         * @throws IllegalArgumentException
409         *             if {@code value} is too large to be represented as a {@code Decimal9f}
410         */
411        public static Decimal9f valueOf(Decimal<?> value) {
412                if (value instanceof Decimal9f) {
413                        return (Decimal9f)value;
414                }
415                return valueOfUnscaled(value.unscaledValue(), value.getScale());
416        }
417
418        /**
419         * Returns a {@code Decimal9f} whose value is calculated by rounding
420         * the specified {@link Decimal} argument to scale 9 using
421         * the specified {@code roundingMode}. An exception is thrown if the
422         * specified value is too large to be represented as a {@code Decimal9f}. 
423         *
424         * @param value
425         *            Decimal value to convert into a {@code Decimal9f} 
426         * @param roundingMode
427         *            the rounding mode to apply during the conversion if necessary
428         * @return a {@code Decimal9f} calculated as: <code>round(value)</code>
429         * @throws IllegalArgumentException
430         *             if {@code value} is too large to be represented as a {@code Decimal9f}
431         * @throws ArithmeticException
432         *             if {@code roundingMode==UNNECESSARY} and rounding is
433         *             necessary
434         */
435        public static Decimal9f valueOf(Decimal<?> value, RoundingMode roundingMode) {
436                if (value instanceof Decimal9f) {
437                        return (Decimal9f)value;
438                }
439                return valueOfUnscaled(value.unscaledValue(), value.getScale(), roundingMode);
440        }
441
442        /**
443         * Translates the string representation of a {@code Decimal} into a
444         * {@code Decimal9f}. The string representation consists of an
445         * optional sign, {@code '+'} or {@code '-'} , followed by a sequence of
446         * zero or more decimal digits ("the integer"), optionally followed by a
447         * fraction.
448         * <p>
449         * The fraction consists of a decimal point followed by zero or more decimal
450         * digits. The string must contain at least one digit in either the integer
451         * or the fraction. If the fraction contains more than 9 digits, the 
452         * value is rounded using {@link RoundingMode#HALF_UP HALF_UP} rounding. An 
453         * exception is thrown if the value is too large to be represented as a 
454         * {@code Decimal9f}.
455         *
456         * @param value
457         *            String value to convert into a {@code Decimal9f}
458         * @return a {@code Decimal9f} calculated as: <code>round<sub>HALF_UP</sub>(value)</code>
459         * @throws NumberFormatException
460         *             if {@code value} does not represent a valid {@code Decimal}
461         *             or if the value is too large to be represented as a 
462         *             {@code Decimal9f}
463         */
464        public static Decimal9f valueOf(String value) {
465                return valueOfUnscaled(DEFAULT_CHECKED_ARITHMETIC.parse(value));
466        }
467
468        /**
469         * Translates the string representation of a {@code Decimal} into a
470         * {@code Decimal9f}. The string representation consists of an
471         * optional sign, {@code '+'} or {@code '-'} , followed by a sequence of
472         * zero or more decimal digits ("the integer"), optionally followed by a
473         * fraction.
474         * <p>
475         * The fraction consists of a decimal point followed by zero or more decimal
476         * digits. The string must contain at least one digit in either the integer
477         * or the fraction. If the fraction contains more than 9 digits, the 
478         * value is rounded using the specified {@code roundingMode}. An exception 
479         * is thrown if the value is too large to be represented as a {@code Decimal9f}.
480         *
481         * @param value
482         *            String value to convert into a {@code Decimal9f}
483         * @param roundingMode
484         *            the rounding mode to apply if the fraction contains more than
485         *            9 digits
486         * @return a {@code Decimal9f} calculated as: <code>round(value)</code>
487         * @throws NumberFormatException
488         *             if {@code value} does not represent a valid {@code Decimal}
489         *             or if the value is too large to be represented as a 
490         *             {@code Decimal9f}
491         * @throws ArithmeticException
492         *             if {@code roundingMode==UNNECESSARY} and rounding is
493         *             necessary
494         */
495        public static Decimal9f valueOf(String value, RoundingMode roundingMode) {
496                return valueOfUnscaled(METRICS.getCheckedArithmetic(roundingMode).parse(value));
497        }
498
499        /**
500         * Returns a {@code Decimal9f} whose value is numerically equal to
501         * <code>(unscaledValue &times; 10<sup>-9</sup>)</code>.
502         *
503         * @param unscaledValue
504         *            unscaled value to convert into a {@code Decimal9f}
505         * @return a {@code Decimal9f} calculated as:
506         *         <code>unscaledValue &times; 10<sup>-9</sup></code>
507         */
508        public static Decimal9f valueOfUnscaled(long unscaledValue) {
509                if (unscaledValue == 0) {
510                        return ZERO;
511                }
512                if (unscaledValue == 1) {
513                        return ULP;
514                }
515                if (unscaledValue == ONE_UNSCALED) {
516                        return ONE;
517                }
518                if (unscaledValue == -ONE_UNSCALED) {
519                        return MINUS_ONE;
520                }
521                return new Decimal9f(unscaledValue);
522        }
523
524        /**
525         * Returns a {@code Decimal9f} whose value is numerically equal to
526         * <code>(unscaledValue &times; 10<sup>-scale</sup>)</code>. The result is
527         * rounded to scale 9 using {@link RoundingMode#HALF_UP HALF_UP} 
528         * rounding. An exception is thrown if the specified value is too large 
529         * to be represented as a {@code Decimal9f}.
530         *
531         * @param unscaledValue
532         *            unscaled value to convert into a {@code Decimal9f}
533         * @param scale
534         *            the scale to apply to {@code unscaledValue}
535         * @return a {@code Decimal9f} calculated as:
536         *         <code>round<sub>HALF_UP</sub>(unscaledValue &times; 10<sup>-scale</sup>)</code>
537         * @throws IllegalArgumentException
538         *             if the specified value is too large to be represented as a 
539         *             {@code Decimal9f}
540         */
541        public static Decimal9f valueOfUnscaled(long unscaledValue, int scale) {
542                return valueOfUnscaled(DEFAULT_CHECKED_ARITHMETIC.fromUnscaled(unscaledValue, scale));
543        }
544
545        /**
546         * Returns a {@code Decimal9f} whose value is numerically equal to
547         * <code>(unscaledValue &times; 10<sup>-scale</sup>)</code>. The result
548         * is rounded to scale 9 using the specified {@code roundingMode}. 
549         * An exception is thrown if the specified value is too large to be 
550         * represented as a {@code Decimal9f}.
551         *
552         * @param unscaledValue
553         *            unscaled value to convert into a Decimal9
554         * @param scale
555         *            the scale to apply to {@code unscaledValue}
556         * @param roundingMode
557         *            the rounding mode to apply during the conversion if necessary
558         * @return a {@code Decimal9f} calculated as:
559         *         <code>round(unscaledValue &times; 10<sup>-scale</sup>)</code>
560         * @throws IllegalArgumentException
561         *             if the specified value is too large to be represented as a {@code Decimal9f}
562         */
563        public static Decimal9f valueOfUnscaled(long unscaledValue, int scale, RoundingMode roundingMode) {
564                return valueOfUnscaled(METRICS.getCheckedArithmetic(roundingMode).fromUnscaled(unscaledValue, scale));
565        }
566
567        @Override
568        protected Decimal9f createOrAssign(long unscaled) {
569                return valueOfUnscaled(unscaled);
570        }
571        
572        @Override
573        protected Decimal9f create(long unscaled) {
574                return valueOfUnscaled(unscaled);
575        }
576        
577        @Override
578        protected Decimal9f[] createArray(int length) {
579                return new Decimal9f[length];
580        }
581        
582        /**
583         * Returns this {@code Decimal} as a multipliable factor for typed 
584         * exact multiplication. The second factor is passed to one of the
585         * {@code by(..)} methods of the returned multiplier. The scale of
586         * the result is the sum of the scales of {@code this} Decimal and the
587         * second factor passed to the {@code by(..)} method.
588         * <p>
589         * The method is similar to {@link #multiplyExact(Decimal) multiplyExact(Decimal)} but the result
590         * is retrieved in exact typed form with the correct result scale. 
591         * <p>
592         * For instance one can write:
593         * <pre>
594         * Decimal11f product = this.multiplyExact().by(Decimal2f.FIVE);
595         * </pre>
596         * 
597         * @return a multipliable object encapsulating this Decimal as first factor
598         *             of an exact multiplication
599         */
600        public Multipliable9f multiplyExact() {
601                return new Multipliable9f(this);
602        }
603
604        @Override
605        public MutableDecimal9f toMutableDecimal() {
606                return new MutableDecimal9f(this);
607        }
608
609        @Override
610        public Decimal9f toImmutableDecimal() {
611                return this;
612        }
613}