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