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.arithmetic;
025
026import java.math.BigDecimal;
027import java.math.RoundingMode;
028
029import org.decimal4j.scale.Scale0f;
030import org.decimal4j.truncate.DecimalRounding;
031import org.decimal4j.truncate.UncheckedRounding;
032
033/**
034 * Arithmetic implementation with rounding for the special case with
035 * {@link Scale0f}, that is, for longs. If an operation leads to an overflow the
036 * result is silently truncated.
037 */
038public final class UncheckedScale0fRoundingArithmetic extends AbstractUncheckedScale0fArithmetic {
039
040        private final DecimalRounding rounding;
041
042        /**
043         * Constructor for decimal arithmetic with the given rounding.
044         * 
045         * @param roundingMode
046         *            the rounding mode to use for all decimal arithmetic operations
047         */
048        public UncheckedScale0fRoundingArithmetic(RoundingMode roundingMode) {
049                this(DecimalRounding.valueOf(roundingMode));
050        }
051
052        /**
053         * Constructor for decimal arithmetic with the given rounding.
054         * 
055         * @param rounding
056         *            the rounding to apply to all decimal arithmetic operations
057         */
058        public UncheckedScale0fRoundingArithmetic(DecimalRounding rounding) {
059                this.rounding = rounding;
060        }
061
062        @Override
063        public final RoundingMode getRoundingMode() {
064                return rounding.getRoundingMode();
065        }
066
067        @Override
068        public final UncheckedRounding getTruncationPolicy() {
069                return UncheckedRounding.valueOf(getRoundingMode());
070        }
071
072        @Override
073        public final long addUnscaled(long uDecimal, long unscaled, int scale) {
074                return Add.addLongUnscaled(rounding, uDecimal, unscaled, scale);
075        }
076
077        @Override
078        public final long subtractUnscaled(long uDecimal, long unscaled, int scale) {
079                return Sub.subtractLongUnscaled(rounding, uDecimal, unscaled, scale);
080        }
081
082        @Override
083        public final long multiplyByUnscaled(long uDecimal, long unscaled, int scale) {
084                return Mul.multiplyByUnscaled(rounding, uDecimal, unscaled, scale);
085        }
086
087        @Override
088        public final long divide(long uDecimalDividend, long uDecimalDivisor) {
089                return Div.divideByLong(rounding, uDecimalDividend, uDecimalDivisor);
090        }
091
092        @Override
093        public final long divideByLong(long uDecimalDividend, long lDivisor) {
094                return Div.divideByLong(rounding, uDecimalDividend, lDivisor);
095        }
096        
097        @Override
098        public final long divideByUnscaled(long uDecimal, long unscaled, int scale) {
099                return Div.divideByUnscaled(rounding, uDecimal, unscaled, scale);
100        }
101
102        @Override
103        public final long avg(long uDecimal1, long uDecimal2) {
104                return Avg.avg(this, rounding, uDecimal1, uDecimal2);
105        }
106
107        @Override
108        public final long invert(long uDecimal) {
109                return Invert.invertLong(rounding, uDecimal);
110        }
111
112        @Override
113        public final long shiftLeft(long uDecimal, int positions) {
114                return Shift.shiftLeft(rounding, uDecimal, positions);
115        }
116
117        @Override
118        public final long shiftRight(long uDecimal, int positions) {
119                return Shift.shiftRight(rounding, uDecimal, positions);
120        }
121
122        @Override
123        public final long divideByPowerOf10(long uDecimal, int n) {
124                return Pow10.divideByPowerOf10(rounding, uDecimal, n);
125        }
126
127        @Override
128        public final long multiplyByPowerOf10(long uDecimal, int positions) {
129                return Pow10.multiplyByPowerOf10(rounding, uDecimal, positions);
130        }
131
132        @Override
133        public final long sqrt(long uDecimal) {
134                return Sqrt.sqrtLong(rounding, uDecimal);
135        }
136
137        @Override
138        public final long pow(long uDecimal, int exponent) {
139                return Pow.powLong(this, rounding, uDecimal, exponent);
140        }
141
142        @Override
143        public final long round(long uDecimal, int precision) {
144                return Round.round(this, rounding, uDecimal, precision);
145        }
146
147        @Override
148        public final long toUnscaled(long uDecimal, int scale) {
149                return UnscaledConversion.unscaledToUnscaled(rounding, scale, this, uDecimal);
150        }
151        
152        @Override
153        public final float toFloat(long uDecimal) {
154                return FloatConversion.longToFloat(this, rounding, uDecimal);
155        }
156
157        @Override
158        public final double toDouble(long uDecimal) {
159                return DoubleConversion.longToDouble(this, rounding, uDecimal);
160        }
161
162        @Override
163        public final long fromUnscaled(long unscaledValue, int scale) {
164                return UnscaledConversion.unscaledToLong(this, rounding, unscaledValue, scale);
165        }
166
167        @Override
168        public final long fromFloat(float value) {
169                return FloatConversion.floatToLong(rounding, value);
170        }
171
172        @Override
173        public final long fromDouble(double value) {
174                return DoubleConversion.doubleToLong(rounding, value);
175        }
176
177        @Override
178        public final long fromBigDecimal(BigDecimal value) {
179                return BigDecimalConversion.bigDecimalToLong(getRoundingMode(), value);
180        }
181
182        @Override
183        public final long parse(String value) {
184                return StringConversion.parseLong(this, rounding, value, 0, value.length());
185        }
186        
187        @Override
188        public final long parse(CharSequence value, int start, int end) {
189                return StringConversion.parseLong(this, rounding, value, start, end);
190        }
191}