001/** 002 * Copyright (c) 2012, 2014, Credit Suisse (Anatole Tresch), Werner Keil and others by the @author tag. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 005 * use this file except in compliance with the License. You may obtain a copy of 006 * the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 012 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 013 * License for the specific language governing permissions and limitations under 014 * the License. 015 */ 016package org.javamoney.moneta.spi; 017 018import java.math.BigDecimal; 019import java.math.MathContext; 020import java.util.Objects; 021 022import javax.money.NumberValue; 023 024/** 025 * Default implementation of {@link NumberValue} based on {@link BigDecimal}. 026 * 027 * @author Anatole Tresch 028 * @author Werner Keil 029 */ 030public final class DefaultNumberValue extends NumberValue { 031 032 /** 033 * serialVersionUID. 034 */ 035 private static final long serialVersionUID = 1L; 036 /** The numeric value. */ 037 private final Number number; 038 039 /** 040 * The value 1, with a scale of 0.<br> 041 * Backed by {@link BigDecimal#ONE} 042 * 043 * @since 0.8 044 */ 045 public static final NumberValue ONE = new DefaultNumberValue(BigDecimal.ONE); 046 047 public DefaultNumberValue(Number number) { 048 this.number = Objects.requireNonNull(number, "Number required"); 049 } 050 051 /** 052 * Creates a new instance of {@link NumberValue}, using the given number. 053 * 054 * @param number 055 * The numeric part, not null. 056 * @return A new instance of {@link NumberValue}. 057 */ 058 public static NumberValue of(Number number) { 059 return new DefaultNumberValue(number); 060 } 061 062 /* 063 * (non-Javadoc) 064 * @see org.javamoney.bp.NumberValue#getNumberType() 065 */ 066 @Override 067 public Class<?> getNumberType() { 068 return this.number.getClass(); 069 } 070 071 /* 072 * (non-Javadoc) 073 * @see org.javamoney.bp.NumberValue#getPrecision() 074 */ 075 @Override 076 public int getPrecision() { 077 return numberValue(BigDecimal.class).precision(); 078 } 079 080 /* 081 * (non-Javadoc) 082 * @see org.javamoney.bp.NumberValue#getScale() 083 */ 084 @Override 085 public int getScale() { 086 return getBigDecimal(number).scale(); 087 } 088 089 /* 090 * (non-Javadoc) 091 * @see org.javamoney.bp.NumberValue#getIntValue() 092 */ 093 @Override 094 public int intValue() { 095 return this.number.intValue(); 096 } 097 098 /* 099 * (non-Javadoc) 100 * @see org.javamoney.bp.NumberValue#getIntValueExact() 101 */ 102 @Override 103 public int intValueExact() { 104 return getBigDecimal(number).intValueExact(); 105 } 106 107 /* 108 * (non-Javadoc) 109 * @see org.javamoney.bp.NumberValue#getLongValue() 110 */ 111 @Override 112 public long longValue() { 113 return this.number.longValue(); 114 } 115 116 /* 117 * (non-Javadoc) 118 * @see org.javamoney.bp.NumberValue#getLongValueExact() 119 */ 120 @Override 121 public long longValueExact() { 122 return getBigDecimal(number).longValueExact(); 123 } 124 125 /* 126 * (non-Javadoc) 127 * @see org.javamoney.bp.NumberValue#getFloatValue() 128 */ 129 @Override 130 public float floatValue() { 131 return this.number.floatValue(); 132 } 133 134 /* 135 * (non-Javadoc) 136 * @see org.javamoney.bp.NumberValue#getDoubleValue() 137 */ 138 @Override 139 public double doubleValue() { 140 return this.number.doubleValue(); 141 } 142 143 /* 144 * (non-Javadoc) 145 * @see org.javamoney.bp.NumberValue#getDoubleValueExact() 146 */ 147 @Override 148 public double doubleValueExact() { 149 double d = this.number.doubleValue(); 150 if (d == Double.NEGATIVE_INFINITY || d == Double.POSITIVE_INFINITY) { 151 throw new ArithmeticException("Unable to convert to double: " 152 + this.number); 153 } 154 return d; 155 } 156 157 /* 158 * (non-Javadoc) 159 * @see org.javamoney.bp.NumberValue#getAmountFractionNumerator() 160 */ 161 @Override 162 public long getAmountFractionNumerator(){ 163 BigDecimal bd = getBigDecimal(number).remainder(BigDecimal.ONE); 164 return bd.movePointRight(getScale()).longValueExact(); 165 } 166 167 /* 168 * (non-Javadoc) 169 * @see org.javamoney.bp.NumberValue#getAmountFractionDenominator() 170 */ 171 @Override 172 public long getAmountFractionDenominator(){ 173 return BigDecimal.valueOf(10).pow(getScale()).longValueExact(); 174 } 175 176 /* 177 * (non-Javadoc) 178 * @see org.javamoney.bp.NumberValue#getNumberValue(java.lang.Class) 179 */ 180 @Override 181 public <T extends Number> T numberValue(Class<T> numberType) { 182 return ConvertNumberValue.of(numberType, number); 183 } 184 185 /* 186 * (non-Javadoc) 187 * @see org.javamoney.bp.NumberValue#round(java.math.MathContext) 188 */ 189 @Override 190 public NumberValue round(MathContext mathContext) { 191 if (this.number instanceof BigDecimal) { 192 return new DefaultNumberValue(((BigDecimal) this.number).round(mathContext)); 193 } 194 return new DefaultNumberValue(new BigDecimal(this.number.toString()).round(mathContext)); 195 } 196 197 /* 198 * (non-Javadoc) 199 * @see org.javamoney.bp.NumberValue#numberValueExact(java.lang.Class) 200 */ 201 @Override 202 public <T extends Number> T numberValueExact(Class<T> numberType) { 203 return ConvertNumberValue.ofExact(numberType, number); 204 } 205 206 /* 207 * (non-Javadoc) 208 * @see java.lang.Object#toString() 209 */ 210 @Override 211 public String toString() { 212 return String.valueOf(number); 213 } 214 215 /** 216 * Creates a {@link BigDecimal} from the given {@link Number} doing the valid conversion 217 * depending the type given. 218 * 219 * @param num 220 * the number type 221 * @return the corresponding {@link BigDecimal} 222 */ 223 protected static BigDecimal getBigDecimal(Number num) { 224 return ConvertBigDecimal.of(num); 225 } 226 227}