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