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