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.api.DecimalArithmetic; 027import org.decimal4j.truncate.DecimalRounding; 028import org.decimal4j.truncate.OverflowMode; 029 030/** 031 * Provides static methods to invert a Decimal number, that is, to calculate 032 * {@code 1/x}. 033 */ 034final class Invert { 035 036 /** 037 * Inverts the specified long value truncating the result if necessary. 038 * 039 * @param lValue 040 * the long value to invert 041 * @return <tt>round<sub>DOWN</sub>(1/lValue)</tt> 042 * @throws ArithmeticException 043 * if {@code lValue == 0} 044 */ 045 public static final long invertLong(long lValue) { 046 if (lValue == 0) { 047 throw new ArithmeticException("Division by zero: " + lValue + "^-1"); 048 } 049 if (lValue == 1) { 050 return 1; 051 } 052 if (lValue == -1) { 053 return -1; 054 } 055 return 0; 056 } 057 058 /** 059 * Inverts the specified long value rounding the result if necessary. 060 * 061 * @param rounding 062 * the rounding to apply if necessary 063 * @param lValue 064 * the long value to invert 065 * @return <tt>round(1/lValue)</tt> 066 * @throws ArithmeticException 067 * if {@code lValue == 0} or if 068 * {@code roundingMode==UNNECESSARY} and rounding is necessary 069 */ 070 public static final long invertLong(DecimalRounding rounding, long lValue) { 071 // special cases first 072 if (lValue == 0) { 073 throw new ArithmeticException("Division by zero: " + lValue + "^-1"); 074 } 075 if (lValue == 1) { 076 return 1; 077 } 078 if (lValue == -1) { 079 return -1; 080 } 081 return Rounding.calculateRoundingIncrementForDivision(rounding, 0, 1, lValue); 082 } 083 084 /** 085 * Inverts the specified unscaled decimal value truncating the result if 086 * necessary. 087 * 088 * @param arith 089 * the arithmetic associated with the given value 090 * @param uDecimal 091 * the unscaled decimal value to invert 092 * @return <tt>round<sub>DOWN</sub>(1/uDecimal)</tt> 093 * @throws ArithmeticException 094 * if {@code uDecimalDividend} is zero or if an overflow occurs 095 * and the arithmetics {@link OverflowMode} is set to throw an 096 * exception 097 * @see DecimalArithmetic#divide(long, long) 098 */ 099 public static final long invert(DecimalArithmetic arith, long uDecimal) { 100 // special cases are handled by divide 101 return arith.divide(arith.one(), uDecimal); 102 } 103 104 /** 105 * Inverts the specified unscaled decimal value rounding the result if 106 * necessary. 107 * 108 * @param arith 109 * the arithmetic associated with the given value 110 * @param rounding 111 * the rounding to apply if necessary 112 * @param uDecimal 113 * the unscaled decimal value to invert 114 * @return <tt>round(1/uDecimal)</tt> 115 * @throws ArithmeticException 116 * if {@code uDecimalDividend} is zero, if {@code roundingMode} 117 * is UNNECESSARY and rounding is necessary or if an overflow 118 * occurs and the arithmetics {@link OverflowMode} is set to 119 * throw an exception 120 * @see DecimalArithmetic#divide(long, long) 121 */ 122 public static final long invert(DecimalArithmetic arith, DecimalRounding rounding, long uDecimal) { 123 // special cases are handled by divide 124 return arith.divide(arith.one(), uDecimal); 125 } 126 127 // no instances 128 private Invert() { 129 super(); 130 } 131}