All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jopendocument.util.DecimalUtils Maven / Gradle / Ivy

Go to download

jOpenDocument is a free library for developers looking to use Open Document files without OpenOffice.org.

The newest version!
/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 * 
 * Copyright 2008-2013 jOpenDocument, by ILM Informatique. All rights reserved.
 * 
 * The contents of this file are subject to the terms of the GNU
 * General Public License Version 3 only ("GPL").  
 * You may not use this file except in compliance with the License. 
 * You can obtain a copy of the License at http://www.gnu.org/licenses/gpl-3.0.html
 * See the License for the specific language governing permissions and limitations under the License.
 * 
 * When distributing the software, include this License Header Notice in each file.
 * 
 */

package org.jopendocument.util;

import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;

public class DecimalUtils {

    /**
     * Useful to pass to {@link BigDecimal#divide(BigDecimal, MathContext)} since :
     * 
    *
  • 1234,567.divide(33000) throws java.lang.ArithmeticException: Non-terminating decimal * expansion; no exact representable decimal result
  • *
  • 1234,567.divide(33000, RoundingMode.HALF_UP) = 0,037 : since it isn't exact uses the * dividend scale, thus loosing a lot of precision
  • *
  • 1234,567.divide(33000, HIGH_PRECISION) = 0.03741112121212121212121212121212121
  • *
* You also can't just use the precision of the dividend : * *
     * lowPrecision = new BigDecimal("1E+3");
     * lowPrecision.divide(new BigDecimal("7E+5"), new MathContext(lowPrecision.precision()))) == 0.001;
     * lowPrecision.divide(new BigDecimal("7E+5"), HIGH_PRECISION) == 0.001428571428571428571428571428571429;
     * 
*

* Note: {@link MathContext#DECIMAL128} is different since it uses * {@link RoundingMode#HALF_EVEN} *

*/ static public final MathContext HIGH_PRECISION = new MathContext(MathContext.DECIMAL128.getPrecision(), RoundingMode.HALF_UP); /** * The number of int digits. * * @param d the decimal to use, eg "123.45". * @return number of int digits, never less than 1, eg 3. */ static public int intDigits(BigDecimal d) { return Math.max(1, d.precision() - d.scale()); } /** * The number of decimal digits. * * @param d the decimal to use, eg "123.45" or "120". * @return number of decimal digits, never less than 0, eg 2 or 0. */ static public int decimalDigits(BigDecimal d) { return Math.max(0, d.stripTrailingZeros().scale()); } static public BigDecimal round(BigDecimal d, int decimalDigits) { return round(d, decimalDigits, RoundingMode.HALF_UP); } /** * Round the passed BigDecimal so that only decimalDigits remain after the point. * * @param d the decimal to use, eg "123.4567". * @param decimalDigits the number of digits after the point, eg 1. * @param rmode how to round. * @return d rounded so that only decimalDigits remain, eg "123.5". */ static public BigDecimal round(BigDecimal d, int decimalDigits, RoundingMode rmode) { return d.round(new MathContext(intDigits(d) + decimalDigits, rmode)); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy