001/** 002 * The MIT License (MIT) 003 * 004 * Copyright (c) 2015-2016 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.math.BigDecimal; 027import java.math.BigInteger; 028import java.math.RoundingMode; 029 030import org.decimal4j.api.Decimal; 031import org.decimal4j.api.DecimalArithmetic; 032import org.decimal4j.truncate.TruncationPolicy; 033 034/** 035 * <tt>ScaleMetrics</tt> defines various metrics associated with the scale of a {@link Decimal} number. It is mainly 036 * used internally from code implementing the arithmetic operations of a {@code Decimal}. 037 * <p> 038 * The {@link #getScale() scale} determines the number of fraction digits of the {@code Decimal}. The 039 * {@link #getScaleFactor() scale factor} is the multiplier/divisor for conversions between the {@code Decimal} value 040 * and the unscaled {@code long} value underlying every {@code Decimal}. 041 * <p> 042 * Operations such as {@link #multiplyByScaleFactor(long) multiplyByScaleFactor(..)} are defined here as separate 043 * methods to allow for compiler optimizations. Multiplications and divisions are for instance translated into shifts 044 * and adds by the compiler instead of the more expensive multiplication and division operations with non-constant long 045 * values. 046 * <p> 047 * {@code ScaleMetrics} also provides access to {@link DecimalArithmetic} instances for different rounding modes and 048 * overflow policies. {@code DecimalArithmetic} objects can be used to deal with {@code Decimal} numbers in their 049 * <i>primitive</i> form, meaning that {@code Decimal} numbers are passed to the arithmetic class as unscaled 050 * {@code long} values. 051 */ 052public interface ScaleMetrics { 053 /** 054 * Returns the scale, the number of fraction digits to the right of the decimal point of a {@link Decimal} value. 055 * 056 * @return the scale also known as number of fraction digits 057 */ 058 int getScale(); 059 060 /** 061 * Returns the scale factor, which is 10<sup>f</sup> where {@code f} stands for the {@link #getScale() scale}. 062 * 063 * @return the scale factor 064 */ 065 long getScaleFactor(); 066 067 /** 068 * Returns the {@link #getScaleFactor() scale factor} as a {@link BigInteger} value. 069 * 070 * @return the scale factor as big integer 071 */ 072 BigInteger getScaleFactorAsBigInteger(); 073 074 /** 075 * Returns the {@link #getScaleFactor() scale factor} as a {@link BigDecimal} value with scale zero. 076 * 077 * @return the scale factor as big decimal with scale zero. 078 */ 079 BigDecimal getScaleFactorAsBigDecimal(); 080 081 /** 082 * Returns the number of leading zeros of the scale factor 083 * 084 * @return {@link Long#numberOfLeadingZeros(long)} applied to the scale factor 085 */ 086 int getScaleFactorNumberOfLeadingZeros(); 087 088 /** 089 * Returns the largest integer value that can be represented using this scale. 090 * 091 * @return {@code Long.MAX_VALUE / scaleFactor} 092 */ 093 long getMaxIntegerValue(); 094 095 /** 096 * Returns the smallest integer value that can be represented using this scale. 097 * 098 * @return {@code Long.MIN_VALUE / scaleFactor} 099 */ 100 long getMinIntegerValue(); 101 102 /** 103 * Returns true if the specified integer {@code value} can be represented using this scale. 104 * 105 * @param value 106 * the value to test 107 * @return true if {@code (Long.MIN_VALUE / scaleFactor) <= value <= (Long.MAX_VALUE / scaleFactor)} 108 */ 109 boolean isValidIntegerValue(long value); 110 111 /** 112 * Returns {@code factor*scaleFactor}. 113 * 114 * @param factor 115 * the factor 116 * @return {@code factor*scaleFactor} 117 */ 118 long multiplyByScaleFactor(long factor); 119 120 /** 121 * Returns {@code factor*scaleFactor}, checking for lost information. If the result is out of the range of the 122 * {@code long} type, then an {@code ArithmeticException} is thrown. 123 * 124 * @param factor 125 * the factor 126 * @return {@code factor*scaleFactor} 127 * @throws ArithmeticException 128 * if an overflow occurs 129 */ 130 long multiplyByScaleFactorExact(long factor); 131 132 /** 133 * Returns {@code factor*low32(scaleFactor)} where low32 refers to the low 32 bits of the factor. 134 * 135 * @param factor 136 * the factor 137 * @return {@code factor*low32(scaleFactor)} 138 */ 139 long mulloByScaleFactor(int factor); 140 141 /** 142 * Returns {@code factor*high32(scaleFactor)} where high32 refers to the high 32 bits of the factor. 143 * 144 * @param factor 145 * the factor 146 * @return {@code factor*high32(scaleFactor)} 147 */ 148 long mulhiByScaleFactor(int factor); 149 150 /** 151 * Returns {@code dividend/scaleFactor}. 152 * 153 * @param dividend 154 * the dividend 155 * @return {@code dividend/scaleFactor} 156 */ 157 long divideByScaleFactor(long dividend); 158 159 /** 160 * Returns {@code unsignedDividend/scaleFactor} using unsigned division. 161 * 162 * @param unsignedDividend 163 * the unsigned dividend 164 * @return {@code unsignedDividend/scaleFactor} 165 */ 166 long divideUnsignedByScaleFactor(long unsignedDividend); 167 168 /** 169 * Returns {@code dividend % scaleFactor} also known as reminder. 170 * 171 * @param dividend 172 * the dividend 173 * @return {@code dividend % scaleFactor} 174 */ 175 long moduloByScaleFactor(long dividend); 176 177 /** 178 * Returns the string representation of the specified {@code value} applying this metric's scale. 179 * 180 * @param value 181 * the unscaled decimal to convert to a string 182 * @return a fixed-point string representation of the specified value 183 * @see DecimalArithmetic#toString(long) 184 */ 185 String toString(long value); 186 187 /** 188 * Returns the default arithmetic for this scale performing unchecked operations with rounding mode 189 * {@link RoundingMode#HALF_UP HALF_UP}. 190 * 191 * @return default arithmetic for this scale rounding HALF_UP without overflow checks 192 */ 193 DecimalArithmetic getDefaultArithmetic(); 194 195 /** 196 * Returns the default arithmetic for this scale performing checked operations with rounding mode 197 * {@link RoundingMode#HALF_UP HALF_UP}. 198 * 199 * @return default arithmetic for this scale rounding HALF_UP with overflow checks 200 */ 201 DecimalArithmetic getDefaultCheckedArithmetic(); 202 203 /** 204 * Returns the arithmetic for this scale performing unchecked operations with rounding mode {@link RoundingMode#DOWN 205 * DOWN}. 206 * 207 * @return arithmetic for this scale rounding DOWN without overflow checks 208 */ 209 DecimalArithmetic getRoundingDownArithmetic(); 210 211 /** 212 * Returns the arithmetic for this scale performing unchecked operations with rounding mode 213 * {@link RoundingMode#FLOOR FLOOR}. 214 * 215 * @return arithmetic for this scale rounding FLOOR without overflow checks 216 */ 217 DecimalArithmetic getRoundingFloorArithmetic(); 218 219 /** 220 * Returns the arithmetic for this scale performing unchecked operations with rounding mode 221 * {@link RoundingMode#HALF_EVEN HALF_EVEN}. 222 * 223 * @return arithmetic for this scale rounding HALF_EVEN without overflow checks 224 */ 225 DecimalArithmetic getRoundingHalfEvenArithmetic(); 226 227 /** 228 * Returns the arithmetic for this scale performing unchecked operations with rounding mode 229 * {@link RoundingMode#UNNECESSARY UNNECESSARY}. 230 * 231 * @return default arithmetic for this scale for rounding UNNECESSARY mode without overflow checks 232 */ 233 DecimalArithmetic getRoundingUnnecessaryArithmetic(); 234 235 /** 236 * Returns the arithmetic for this scale that performs all operations with the specified {@code roundingMode} and 237 * without overflow checks. 238 * 239 * @param roundingMode 240 * the rounding mode used by the returned arithmetic 241 * @return arithmetic for this scale with specified rounding mode and without overflow checks 242 */ 243 DecimalArithmetic getArithmetic(RoundingMode roundingMode); 244 245 /** 246 * Returns the arithmetic for this scale that performs all operations with the specified {@code roundingMode} and 247 * with overflow checks. 248 * 249 * @param roundingMode 250 * the rounding mode used by the returned arithmetic 251 * @return arithmetic for this scale with specified rounding mode and with overflow checks 252 */ 253 DecimalArithmetic getCheckedArithmetic(RoundingMode roundingMode); 254 255 /** 256 * Returns the arithmetic for this scale that performs all operations with the specified {@code truncationPolicy}. 257 * 258 * @param truncationPolicy 259 * the truncation policy used by the returned arithmetic 260 * @return arithmetic for this scale with specified truncation policy 261 */ 262 DecimalArithmetic getArithmetic(TruncationPolicy truncationPolicy); 263}