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