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.api.DecimalArithmetic;
030import org.decimal4j.scale.ScaleMetrics;
031import org.decimal4j.truncate.DecimalRounding;
032import org.decimal4j.truncate.OverflowMode;
033import org.decimal4j.truncate.UncheckedRounding;
034
035/**
036 * Arithmetic implementation without rounding for scales other than zero. If an
037 * operation leads to an overflow the result is silently truncated.
038 */
039public final class UncheckedScaleNfTruncatingArithmetic extends AbstractUncheckedScaleNfArithmetic implements
040                DecimalArithmetic {
041
042        /**
043         * Constructor for silent decimal arithmetic with given scale, truncating
044         * {@link RoundingMode#DOWN DOWN} rounding mode and
045         * {@link OverflowMode#UNCHECKED SILENT} overflow mode.
046         * 
047         * @param scaleMetrics
048         *            the scale, a non-negative integer denoting the number of
049         *            digits to the right of the decimal point
050         * @throws IllegalArgumentException
051         *             if scale is negative or uneven
052         */
053        public UncheckedScaleNfTruncatingArithmetic(ScaleMetrics scaleMetrics) {
054                super(scaleMetrics);
055        }
056
057        @Override
058        public final RoundingMode getRoundingMode() {
059                return RoundingMode.DOWN;
060        }
061
062        @Override
063        public final UncheckedRounding getTruncationPolicy() {
064                return UncheckedRounding.DOWN;
065        }
066
067        @Override
068        public final long addUnscaled(long uDecimal, long unscaled, int scale) {
069                return Add.addUnscaledUnscaled(getScaleMetrics(), uDecimal, unscaled, scale);
070        }
071
072        @Override
073        public final long subtractUnscaled(long uDecimal, long unscaled, int scale) {
074                return Sub.subtractUnscaledUnscaled(getScaleMetrics(), uDecimal, unscaled, scale);
075        }
076
077        @Override
078        public final long multiply(long uDecimal1, long uDecimal2) {
079                return Mul.multiply(this, uDecimal1, uDecimal2);
080        }
081
082        @Override
083        public final long multiplyByUnscaled(long uDecimal, long unscaled, int scale) {
084                return Mul.multiplyByUnscaled(uDecimal, unscaled, scale);
085        }
086
087        @Override
088        public final long square(long uDecimal) {
089                return Square.square(getScaleMetrics(), uDecimal);
090        }
091
092        @Override
093        public final long sqrt(long uDecimal) {
094                return Sqrt.sqrt(this, uDecimal);
095        }
096
097        @Override
098        public final long divide(long uDecimalDividend, long uDecimalDivisor) {
099                return Div.divide(this, uDecimalDividend, uDecimalDivisor);
100        }
101
102        @Override
103        public final long divideByLong(long uDecimalDividend, long lDivisor) {
104                return uDecimalDividend / lDivisor;
105        }
106
107        @Override
108        public final long divideByUnscaled(long uDecimal, long unscaled, int scale) {
109                return Div.divideByUnscaled(uDecimal, unscaled, scale);
110        }
111
112        @Override
113        public final long invert(long uDecimal) {
114                return Invert.invert(this, uDecimal);
115        }
116
117        @Override
118        public final long avg(long a, long b) {
119                return Avg.avg(a, b);
120        }
121
122        @Override
123        public final long multiplyByPowerOf10(long uDecimal, int positions) {
124                return Pow10.multiplyByPowerOf10(uDecimal, positions);
125        }
126
127        @Override
128        public final long divideByPowerOf10(long uDecimal, int positions) {
129                return Pow10.divideByPowerOf10(uDecimal, positions);
130        }
131
132        @Override
133        public final long pow(long uDecimal, int exponent) {
134                return Pow.pow(this, DecimalRounding.DOWN, uDecimal, exponent);
135        }
136
137        @Override
138        public final long shiftLeft(long uDecimal, int positions) {
139                return Shift.shiftLeft(DecimalRounding.DOWN, uDecimal, positions);
140        }
141
142        @Override
143        public final long shiftRight(long uDecimal, int positions) {
144                return Shift.shiftRight(DecimalRounding.DOWN, uDecimal, positions);
145        }
146
147        @Override
148        public final long round(long uDecimal, int precision) {
149                return Round.round(this, uDecimal, precision);
150        }
151
152        @Override
153        public final long fromLong(long value) {
154                return LongConversion.longToUnscaled(getScaleMetrics(), value);
155        }
156
157        @Override
158        public final long fromUnscaled(long unscaledValue, int scale) {
159                return UnscaledConversion.unscaledToUnscaled(this, unscaledValue, scale);
160        }
161
162        @Override
163        public final long fromFloat(float value) {
164                return FloatConversion.floatToUnscaled(this, value);
165        }
166
167        @Override
168        public final long fromDouble(double value) {
169                return DoubleConversion.doubleToUnscaled(this, value);
170        }
171
172        @Override
173        public final long fromBigDecimal(BigDecimal value) {
174                return BigDecimalConversion.bigDecimalToUnscaled(getScaleMetrics(), RoundingMode.DOWN, value);
175        }
176
177        @Override
178        public final long toLong(long uDecimal) {
179                return getScaleMetrics().divideByScaleFactor(uDecimal);
180        }
181
182        @Override
183        public final long toUnscaled(long uDecimal, int scale) {
184                return UnscaledConversion.unscaledToUnscaled(scale, this, uDecimal);
185        }
186
187        @Override
188        public final float toFloat(long uDecimal) {
189                return FloatConversion.unscaledToFloat(this, uDecimal);
190        }
191
192        @Override
193        public final double toDouble(long uDecimal) {
194                return DoubleConversion.unscaledToDouble(this, uDecimal);
195        }
196
197        @Override
198        public final long parse(String value) {
199                return StringConversion.parseUnscaledDecimal(this, DecimalRounding.DOWN, value, 0, value.length());
200        }
201        
202        @Override
203        public final long parse(CharSequence value, int start, int end) {
204                return StringConversion.parseUnscaledDecimal(this, DecimalRounding.DOWN, value, start, end);
205        }
206}