简体   繁体   English

Java 四舍五入到小数点后 15 位

[英]Java Rounding to 15 decimal place

I have the below codes round the forward rate to 15 decimal place.我有以下代码将远期利率四舍五入到小数点后 15 位。 When _ForwardRate is 13,555.0, the result return is wrong.当_ForwardRate为13555.0时,返回结果错误。

public double round(double Number, int Decimal_Place) {     
    if (Number==0) return 0;
    double _plug = 0.000001;
    if (Number < 0) {
        _plug = -0.000001;
    }
    //Sometime a number is rounded down to 2.22499999999 by java. 
    //Actual precision is 2.245.  Without this plug, a 2 dp rounding result
    //in 2.22 when it should be 2.23
    double _newNumber = Number;
    if (Decimal_Place==2) {
        _newNumber = _newNumber+_plug;      
    }

    double _number_abs = Math.abs(_newNumber);  
    double _factor = Math.pow(10, Decimal_Place);
    double _rd = Math.round(_number_abs * _factor);
    double _r = _rd/_factor;
    if (Number <= 0)
        _r = _r * -1;

    return _r;
}

Double _ForwardRate = getForward_rate();
BigDecimal _fwdrate_bd = BigDecimal.valueOf(_ForwardRate.doubleValue());
_ForwardRate = round(new Double(_fwdrate_bd.doubleValue()), 15);

Current result当前结果

9,223.372036854777

Expected result预期结果

13,555.000000000000000

Your problem is that Math.round(double a) returns long , and you're overflowing .您的问题是Math.round(double a)返回long ,而您正在溢出

One easy way to do this, is to use BigDecimal :一种简单的方法是使用BigDecimal

public static double round(double number, int decimalPlaces) {
    return BigDecimal.valueOf(number)
                     .setScale(decimalPlaces, RoundingMode.HALF_UP)
                     .doubleValue();
}

This allows you to control the rounding mode.这允许您控制舍入模式。 Note that the rounding done by Math.round() is a HALF_CEILING which isn't supported by setScale() .请注意, Math.round()完成的舍入是setScale()不支持的HALF_CEILING

You might want to consider doing all you math using BigDecimal , if you need that level of precision.如果您需要该级别的精度,您可能需要考虑使用BigDecimal进行所有数学运算。

Consider:考虑:

    double _number_abs = Math.abs(_newNumber);  

At this point, _number_abs contains the value 13555.0此时, _number_abs包含值 13555.0

    double _factor = Math.pow(10, Decimal_Place);

Now _factor contains 1.0E15现在_factor包含1.0E15

    double _rd = Math.round(_number_abs * _factor);

According to the Javadoc根据 Javadoc

Math.round() Returns the closest long to the argument, with ties rounding to positive infinity. Math.round()返回最接近参数的 long,关系四舍五入到正无穷大。

Since _number_abs * _factor is 1.3555E19 , which is larger than Long.MAX_VALUE , the result is Long.MAX_VALUE , ie the "closest" Long to the given value.由于_number_abs * _factor1.3555E19 ,它大于Long.MAX_VALUE ,结果是Long.MAX_VALUE ,即“最接近”给定值的Long

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM