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.arithmetic; 025 026import org.decimal4j.scale.ScaleMetrics; 027import org.decimal4j.truncate.DecimalRounding; 028 029/** 030 * Contains methods to convert from and to long. 031 */ 032final class LongConversion { 033 034 /** 035 * Converts the specified long value to an unscaled value of the scale 036 * defined by the given {@code scaleMetrics}. Performs no overflow checks. 037 * 038 * @param scaleMetrics 039 * the scale metrics defining the result scale 040 * @param value 041 * the long value to convert 042 * @return the value converted to the scale defined by {@code scaleMetrics} 043 */ 044 public static final long longToUnscaledUnchecked(ScaleMetrics scaleMetrics, long value) { 045 return scaleMetrics.multiplyByScaleFactor(value); 046 } 047 048 /** 049 * Converts the specified long value to an unscaled value of the scale 050 * defined by the given {@code scaleMetrics}. An exception is thrown if an 051 * overflow occurs. 052 * 053 * @param scaleMetrics 054 * the scale metrics defining the result scale 055 * @param value 056 * the long value to convert 057 * @return the value converted to the scale defined by {@code scaleMetrics} 058 * @throws IllegalArgumentException 059 * if {@code value} is too large to be represented as a Decimal 060 * with the scale of this factory 061 */ 062 public static final long longToUnscaled(ScaleMetrics scaleMetrics, long value) { 063 if (scaleMetrics.isValidIntegerValue(value)) { 064 return scaleMetrics.multiplyByScaleFactor(value); 065 } 066 throw new IllegalArgumentException( 067 "Overflow: cannot convert " + value + " to Decimal with scale " + scaleMetrics.getScale()); 068 } 069 070 /** 071 * Converts the specified unscaled value to a long truncating the result if 072 * necessary. 073 * 074 * @param scaleMetrics 075 * the scale metrics associated with {@code uDecimal} 076 * @param uDecimal 077 * the unscaled decimal value to convert 078 * @return <tt>round<sub>DOWN</sub>(uDecimal)</tt> 079 */ 080 public static final long unscaledToLong(ScaleMetrics scaleMetrics, long uDecimal) { 081 return scaleMetrics.divideByScaleFactor(uDecimal); 082 } 083 084 /** 085 * Converts the specified unscaled value to a long rounding the result if 086 * necessary. 087 * 088 * @param scaleMetrics 089 * the scale metrics associated with {@code uDecimal} 090 * @param rounding 091 * the rounding to apply during the conversion if necessary 092 * @param uDecimal 093 * the unscaled decimal value to convert 094 * @return <tt>round(uDecimal)</tt> 095 * @throws ArithmeticException 096 * if {@code roundingMode==UNNECESSARY} and rounding is 097 * necessary 098 */ 099 public static final long unscaledToLong(ScaleMetrics scaleMetrics, DecimalRounding rounding, long uDecimal) { 100 final long truncated = scaleMetrics.divideByScaleFactor(uDecimal); 101 final long remainder = uDecimal - scaleMetrics.multiplyByScaleFactor(truncated); 102 return truncated 103 + Rounding.calculateRoundingIncrement(rounding, truncated, remainder, scaleMetrics.getScaleFactor()); 104 } 105 106 // no instances 107 private LongConversion() { 108 super(); 109 } 110}