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