001/* 002 * Copyright (C) 2020 The Guava Authors 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 005 * in compliance with the License. You may obtain a copy of the License at 006 * 007 * http://www.apache.org/licenses/LICENSE-2.0 008 * 009 * Unless required by applicable law or agreed to in writing, software distributed under the License 010 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 011 * or implied. See the License for the specific language governing permissions and limitations under 012 * the License. 013 */ 014 015package com.google.common.math; 016 017import com.google.common.annotations.GwtIncompatible; 018import com.google.common.annotations.J2ktIncompatible; 019import java.math.BigDecimal; 020import java.math.RoundingMode; 021 022/** 023 * A class for arithmetic on {@link BigDecimal} that is not covered by its built-in methods. 024 * 025 * @author Louis Wasserman 026 * @since 30.0 027 */ 028@J2ktIncompatible 029@GwtIncompatible 030@ElementTypesAreNonnullByDefault 031public class BigDecimalMath { 032 private BigDecimalMath() {} 033 034 /** 035 * Returns {@code x}, rounded to a {@code double} with the specified rounding mode. If {@code x} 036 * is precisely representable as a {@code double}, its {@code double} value will be returned; 037 * otherwise, the rounding will choose between the two nearest representable values with {@code 038 * mode}. 039 * 040 * <p>For the case of {@link RoundingMode#HALF_DOWN}, {@code HALF_UP}, and {@code HALF_EVEN}, 041 * infinite {@code double} values are considered infinitely far away. For example, 2^2000 is not 042 * representable as a double, but {@code roundToDouble(BigDecimal.valueOf(2).pow(2000), HALF_UP)} 043 * will return {@code Double.MAX_VALUE}, not {@code Double.POSITIVE_INFINITY}. 044 * 045 * <p>For the case of {@link RoundingMode#HALF_EVEN}, this implementation uses the IEEE 754 046 * default rounding mode: if the two nearest representable values are equally near, the one with 047 * the least significant bit zero is chosen. (In such cases, both of the nearest representable 048 * values are even integers; this method returns the one that is a multiple of a greater power of 049 * two.) 050 * 051 * @throws ArithmeticException if {@code mode} is {@link RoundingMode#UNNECESSARY} and {@code x} 052 * is not precisely representable as a {@code double} 053 * @since 30.0 054 */ 055 public static double roundToDouble(BigDecimal x, RoundingMode mode) { 056 return BigDecimalToDoubleRounder.INSTANCE.roundToDouble(x, mode); 057 } 058 059 private static class BigDecimalToDoubleRounder extends ToDoubleRounder<BigDecimal> { 060 static final BigDecimalToDoubleRounder INSTANCE = new BigDecimalToDoubleRounder(); 061 062 private BigDecimalToDoubleRounder() {} 063 064 @Override 065 double roundToDoubleArbitrarily(BigDecimal bigDecimal) { 066 return bigDecimal.doubleValue(); 067 } 068 069 @Override 070 int sign(BigDecimal bigDecimal) { 071 return bigDecimal.signum(); 072 } 073 074 @Override 075 BigDecimal toX(double d, RoundingMode mode) { 076 return new BigDecimal(d); 077 } 078 079 @Override 080 BigDecimal minus(BigDecimal a, BigDecimal b) { 081 return a.subtract(b); 082 } 083 } 084}