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