当前位置:  开发笔记 > 编程语言 > 正文

中点舍入远离零.net C#Decimal到Java Double

如何解决《中点舍入远离零.netC#Decimal到JavaDouble》经验,为你挑选了1个好方法。

我正在将.NET代码转换为Java并遇到精度不匹配的问题.

.NET代码:

private decimal roundToPrecision(decimal number, decimal roundPrecision)
{
    if (roundPrecision == 0)
        return number;
    decimal numberDecimalMultiplier = Math.Round(number / roundPrecision, MidpointRounding.AwayFromZero);
    return numberDecimalMultiplier * roundPrecision;
}

roundToPrecision(8.7250, 0.05);上面代码中的调用函数给出了我8.75期望的函数.

将函数转换/转换为Java如下.我找不到确切的 Math.Round选择.

Java代码:

public double roundToPrecision(double number, double roundPrecision) {
    if (roundPrecision == 0)
        return number;
    int len = Double.toString(roundPrecision).split("\\.")[1].length();
    double divisor = 0d;
    switch (len) {
        case 1:
            divisor = 10d;
            break;
        case 2:
            divisor = 100d;
            break;
        case 3:
            divisor = 1000d;
            break;
        case 4:
            divisor = 10000d;
            break;
    }
    double numberDecimalMultiplier = Math.round(number / roundPrecision);
    double res = numberDecimalMultiplier * roundPrecision;
    return Math.round(res * divisor) / divisor;
}

调用roundToPrecision(8.7250, 0.05);Java代码给了我8.7这个并不正确.

我甚至尝试BigDecimal在Java中使用引用修改代码如下C#Double Rounding但没有运气.

public double roundToPrecision(double number, double roundPrecision) {
    if (roundPrecision == 0)
        return number;
    int len = Double.toString(roundPrecision).split("\\.")[1].length();
    double divisor = 0d;
    switch (len) {
        case 1:
            divisor = 10d;
            break;
        case 2:
            divisor = 100d;
            break;
        case 3:
            divisor = 1000d;
            break;
        case 4:
            divisor = 10000d;
            break;
    }
    BigDecimal b = new BigDecimal(number / roundPrecision);
    b = b.setScale(len,BigDecimal.ROUND_UP);
    double numberDecimalMultiplier = Math.round(b.doubleValue());
    double res = numberDecimalMultiplier * roundPrecision;
    return Math.round(res * divisor) / divisor;
}

请指导我为解决这个问题需要做些什么.

以下是一些尝试的方案.

number = 10.05; precision = .1; 预期= 10.1;

number = 10.12; precision = .01; 预期= 10.12;

number = 8.7250; precision = 0.05; 预期= 8.75;

number = 10.999; precision = 2; 预期= 10;

number = 6.174999999999999; precision = 0.05; 预期= 6.20;

注意:我有超过6万个数字,精度可以从1位小数到4位小数不等..NET的输出应该与Java完全匹配.



1> gunnerone..:

问题来自于如何在内存中存储和表示双精度数与小数数.有关更多细节,请参阅以下链接:双打 小数

我们来看看它们在代码中的工作方式.使用双精度,参数为8.725和0.05. number / roundPrecision给出174.499...,因为双打不能完全代表174.5.随着小数number / roundPrecision给人174.5,小数都能够准确地表示这一点.所以当174.499...得到四舍五入时,它会向下舍入174而不是175.

使用BigDecimal是朝着正确方向迈出的一步.但是如何在代码中使用它是一个问题.当您创建BigDecimal值时会出现问题.

BigDecimal b = new BigDecimal(number / roundPrecision);

BigDecimal是从双重创建的,因此不精确已经存在.如果你能够BigDecimal从一个更好的字符串创建参数.

public static BigDecimal roundToPrecision(BigDecimal number, BigDecimal roundPrecision) {
    if (roundPrecision.signum() == 0)
        return number;
    BigDecimal numberDecimalMultiplier = number.divide(roundPrecision, RoundingMode.HALF_DOWN).setScale(0, RoundingMode.HALF_UP);
    return numberDecimalMultiplier.multiply(roundPrecision);
}


BigDecimal n = new BigDecimal("-8.7250");
BigDecimal p = new BigDecimal("0.05");
BigDecimal r = roundToPrecision(n, p);

如果函数必须接受并返回双精度数:

public static double roundToPrecision(double number, double roundPrecision)
{
    BigDecimal numberBig = new BigDecimal(number).
            setScale(10, BigDecimal.ROUND_HALF_UP);
    BigDecimal roundPrecisionBig = BigDecimal.valueOf(roundPrecision);
    if (roundPrecisionBig.signum() == 0)
        return number;
    BigDecimal numberDecimalMultiplier = numberBig.divide(roundPrecisionBig, RoundingMode.HALF_DOWN).setScale(0, RoundingMode.HALF_UP);
    return numberDecimalMultiplier.multiply(roundPrecisionBig).doubleValue();
}

请记住,双精度数不能精确地表示小数可以表示的相同值.因此返回double的函数不能具有返回小数的原始C#函数的确切输出.

推荐阅读
郑小蒜9299_941611_G
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有