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.exact; 025 026import java.util.Objects; 027 028import org.decimal4j.api.Decimal; 029import org.decimal4j.immutable.Decimal0f; 030import org.decimal4j.immutable.Decimal1f; 031import org.decimal4j.immutable.Decimal2f; 032import org.decimal4j.immutable.Decimal3f; 033import org.decimal4j.immutable.Decimal4f; 034import org.decimal4j.immutable.Decimal14f; 035import org.decimal4j.immutable.Decimal15f; 036import org.decimal4j.immutable.Decimal16f; 037import org.decimal4j.immutable.Decimal17f; 038import org.decimal4j.immutable.Decimal18f; 039import org.decimal4j.mutable.MutableDecimal0f; 040import org.decimal4j.mutable.MutableDecimal1f; 041import org.decimal4j.mutable.MutableDecimal2f; 042import org.decimal4j.mutable.MutableDecimal3f; 043import org.decimal4j.mutable.MutableDecimal4f; 044import org.decimal4j.scale.Scale14f; 045 046/** 047 * A {@code Multipliable14f} encapsulates a Decimal of scale 14 and facilitates 048 * exact typed multiplication. The multipliable object acts as first factor in the multiplication 049 * and provides a set of overloaded methods for different scales. Each one of those methods 050 * delivers a different result scale which represents the appropriate scale for the product of 051 * an exact multiplication. 052 * <p> 053 * A {@code Multipliable14f} object is returned by {@link Decimal14f#multiplyExact()}, 054 * hence an exact typed multiplication can be written as: 055 * <pre> 056 * Decimal14f value = ... //some value 057 * Decimal16f product = value.multiplyExact().by(Decimal2f.FIVE); 058 * </pre> 059 */ 060public final class Multipliable14f { 061 062 private final Decimal<Scale14f> value; 063 064 /** 065 * Constructor with Decimal value to be encapsulated. 066 * @param value the decimal value to be wrapped as a multipliable object 067 */ 068 public Multipliable14f(Decimal<Scale14f> value) { 069 this.value = Objects.requireNonNull(value, "value cannot be null"); 070 } 071 072 /** 073 * Returns the value underlying this Multipliable14f. 074 * @return the Decimal value wrapped by this multipliable object 075 */ 076 public Decimal<Scale14f> getValue() { 077 return value; 078 } 079 080 /** 081 * Returns a {@code Decimal} whose value is {@code (this * factor)}. The 082 * result is exact and has scale 14 which is the sum of the scales 083 * of the Decimal that this multipliable object represents and the scale of 084 * the {@code factor} argument. An {@link ArithmeticException} is thrown if the 085 * product is out of the possible range for a {@code Decimal14f}. 086 * <p> 087 * Note that the result is <i>always</i> a new instance. 088 * 089 * @param factor 090 * the factor to multiply with the Decimal that this multipliable represents 091 * @return <tt>(this * factor)</tt> 092 * @throws ArithmeticException 093 * if an overflow occurs and product is out of the possible 094 * range for a {@code Decimal14f} 095 */ 096 public Decimal14f by(Decimal0f factor) { 097 return Decimal14f.valueOf(this.value.multiplyExact(factor)); 098 } 099 /** 100 * Returns a {@code Decimal} whose value is {@code (this * factor)}. The 101 * result is exact and has scale 14 which is the sum of the scales 102 * of the Decimal that this multipliable object represents and the scale of 103 * the {@code factor} argument. An {@link ArithmeticException} is thrown if the 104 * product is out of the possible range for a {@code Decimal14f}. 105 * <p> 106 * Note that the result is <i>always</i> a new instance. 107 * 108 * @param factor 109 * the factor to multiply with the Decimal that this multipliable represents 110 * @return <tt>(this * factor)</tt> 111 * @throws ArithmeticException 112 * if an overflow occurs and product is out of the possible 113 * range for a {@code Decimal14f} 114 */ 115 public Decimal14f by(MutableDecimal0f factor) { 116 return Decimal14f.valueOf(this.value.multiplyExact(factor)); 117 } 118 119 /** 120 * Returns a {@code Decimal} whose value is {@code (this * factor)}. The 121 * result is exact and has scale 15 which is the sum of the scales 122 * of the Decimal that this multipliable object represents and the scale of 123 * the {@code factor} argument. An {@link ArithmeticException} is thrown if the 124 * product is out of the possible range for a {@code Decimal15f}. 125 * <p> 126 * Note that the result is <i>always</i> a new instance. 127 * 128 * @param factor 129 * the factor to multiply with the Decimal that this multipliable represents 130 * @return <tt>(this * factor)</tt> 131 * @throws ArithmeticException 132 * if an overflow occurs and product is out of the possible 133 * range for a {@code Decimal15f} 134 */ 135 public Decimal15f by(Decimal1f factor) { 136 return Decimal15f.valueOf(this.value.multiplyExact(factor)); 137 } 138 /** 139 * Returns a {@code Decimal} whose value is {@code (this * factor)}. The 140 * result is exact and has scale 15 which is the sum of the scales 141 * of the Decimal that this multipliable object represents and the scale of 142 * the {@code factor} argument. An {@link ArithmeticException} is thrown if the 143 * product is out of the possible range for a {@code Decimal15f}. 144 * <p> 145 * Note that the result is <i>always</i> a new instance. 146 * 147 * @param factor 148 * the factor to multiply with the Decimal that this multipliable represents 149 * @return <tt>(this * factor)</tt> 150 * @throws ArithmeticException 151 * if an overflow occurs and product is out of the possible 152 * range for a {@code Decimal15f} 153 */ 154 public Decimal15f by(MutableDecimal1f factor) { 155 return Decimal15f.valueOf(this.value.multiplyExact(factor)); 156 } 157 158 /** 159 * Returns a {@code Decimal} whose value is {@code (this * factor)}. The 160 * result is exact and has scale 16 which is the sum of the scales 161 * of the Decimal that this multipliable object represents and the scale of 162 * the {@code factor} argument. An {@link ArithmeticException} is thrown if the 163 * product is out of the possible range for a {@code Decimal16f}. 164 * <p> 165 * Note that the result is <i>always</i> a new instance. 166 * 167 * @param factor 168 * the factor to multiply with the Decimal that this multipliable represents 169 * @return <tt>(this * factor)</tt> 170 * @throws ArithmeticException 171 * if an overflow occurs and product is out of the possible 172 * range for a {@code Decimal16f} 173 */ 174 public Decimal16f by(Decimal2f factor) { 175 return Decimal16f.valueOf(this.value.multiplyExact(factor)); 176 } 177 /** 178 * Returns a {@code Decimal} whose value is {@code (this * factor)}. The 179 * result is exact and has scale 16 which is the sum of the scales 180 * of the Decimal that this multipliable object represents and the scale of 181 * the {@code factor} argument. An {@link ArithmeticException} is thrown if the 182 * product is out of the possible range for a {@code Decimal16f}. 183 * <p> 184 * Note that the result is <i>always</i> a new instance. 185 * 186 * @param factor 187 * the factor to multiply with the Decimal that this multipliable represents 188 * @return <tt>(this * factor)</tt> 189 * @throws ArithmeticException 190 * if an overflow occurs and product is out of the possible 191 * range for a {@code Decimal16f} 192 */ 193 public Decimal16f by(MutableDecimal2f factor) { 194 return Decimal16f.valueOf(this.value.multiplyExact(factor)); 195 } 196 197 /** 198 * Returns a {@code Decimal} whose value is {@code (this * factor)}. The 199 * result is exact and has scale 17 which is the sum of the scales 200 * of the Decimal that this multipliable object represents and the scale of 201 * the {@code factor} argument. An {@link ArithmeticException} is thrown if the 202 * product is out of the possible range for a {@code Decimal17f}. 203 * <p> 204 * Note that the result is <i>always</i> a new instance. 205 * 206 * @param factor 207 * the factor to multiply with the Decimal that this multipliable represents 208 * @return <tt>(this * factor)</tt> 209 * @throws ArithmeticException 210 * if an overflow occurs and product is out of the possible 211 * range for a {@code Decimal17f} 212 */ 213 public Decimal17f by(Decimal3f factor) { 214 return Decimal17f.valueOf(this.value.multiplyExact(factor)); 215 } 216 /** 217 * Returns a {@code Decimal} whose value is {@code (this * factor)}. The 218 * result is exact and has scale 17 which is the sum of the scales 219 * of the Decimal that this multipliable object represents and the scale of 220 * the {@code factor} argument. An {@link ArithmeticException} is thrown if the 221 * product is out of the possible range for a {@code Decimal17f}. 222 * <p> 223 * Note that the result is <i>always</i> a new instance. 224 * 225 * @param factor 226 * the factor to multiply with the Decimal that this multipliable represents 227 * @return <tt>(this * factor)</tt> 228 * @throws ArithmeticException 229 * if an overflow occurs and product is out of the possible 230 * range for a {@code Decimal17f} 231 */ 232 public Decimal17f by(MutableDecimal3f factor) { 233 return Decimal17f.valueOf(this.value.multiplyExact(factor)); 234 } 235 236 /** 237 * Returns a {@code Decimal} whose value is {@code (this * factor)}. The 238 * result is exact and has scale 18 which is the sum of the scales 239 * of the Decimal that this multipliable object represents and the scale of 240 * the {@code factor} argument. An {@link ArithmeticException} is thrown if the 241 * product is out of the possible range for a {@code Decimal18f}. 242 * <p> 243 * Note that the result is <i>always</i> a new instance. 244 * 245 * @param factor 246 * the factor to multiply with the Decimal that this multipliable represents 247 * @return <tt>(this * factor)</tt> 248 * @throws ArithmeticException 249 * if an overflow occurs and product is out of the possible 250 * range for a {@code Decimal18f} 251 */ 252 public Decimal18f by(Decimal4f factor) { 253 return Decimal18f.valueOf(this.value.multiplyExact(factor)); 254 } 255 /** 256 * Returns a {@code Decimal} whose value is {@code (this * factor)}. The 257 * result is exact and has scale 18 which is the sum of the scales 258 * of the Decimal that this multipliable object represents and the scale of 259 * the {@code factor} argument. An {@link ArithmeticException} is thrown if the 260 * product is out of the possible range for a {@code Decimal18f}. 261 * <p> 262 * Note that the result is <i>always</i> a new instance. 263 * 264 * @param factor 265 * the factor to multiply with the Decimal that this multipliable represents 266 * @return <tt>(this * factor)</tt> 267 * @throws ArithmeticException 268 * if an overflow occurs and product is out of the possible 269 * range for a {@code Decimal18f} 270 */ 271 public Decimal18f by(MutableDecimal4f factor) { 272 return Decimal18f.valueOf(this.value.multiplyExact(factor)); 273 } 274 275 276 /** 277 * Returns a hash code for this <tt>Multipliable14f</tt> which happens to be the 278 * hash code of the underlying {@code Decimal14f} value. 279 * 280 * @return a hash code value for this object 281 * @see Decimal#hashCode() 282 */ 283 @Override 284 public int hashCode() { 285 return value.hashCode(); 286 } 287 288 /** 289 * Compares this Multipliable14f to the specified object. The result is {@code true} 290 * if and only if the argument is a {@code Multipliable14f} with an equal underlying 291 * {@link #getValue() value}. 292 * 293 * @param obj 294 * the object to compare with 295 * @return {@code true} if the argument is a {@code Multipliable14f} and if its value 296 * is equal to this multipliables's value; {@code false} otherwise 297 * @see #getValue() 298 * @see Decimal#equals(Object) 299 */ 300 @Override 301 public boolean equals(Object obj) { 302 if (this == obj) return true; 303 if (obj == null) return false; 304 if (getClass() != obj.getClass()) return false; 305 return value.equals(((Multipliable14f)obj).value); 306 } 307 308 /** 309 * Returns a string representation of this {@code Multipliable14f} which is 310 * simply the string representation of the underlying Decimal {@link #getValue() value}. 311 * 312 * @return a {@code String} Decimal representation of this {@code Multipliable14f}'s 313 * value with all the fraction digits (including trailing zeros) 314 * @see #getValue() 315 * @see Decimal#toString() 316 */ 317 @Override 318 public String toString() { 319 return value.toString(); 320 } 321}