【问题标题】:Problem on getting digits in a double variable在双变量中获取数字的问题
【发布时间】:2011-05-13 14:07:06
【问题描述】:

我的 java 程序中需要的一个函数有点问题。我想检查一个“双”变量的总位数。 (例如:5 应该返回 1,5.0034 应该返回 5,2.04 应该返回 3。)我的函数是这样的:

private int getDoubleLength (double a) {
        int len = 0;
        while (a != (int) a) {
            a *= 10;
        }
        while (a > 1) {
            len ++;
            a/=10;
        }
        System.out.println(String.format("Double %f has %d digits.",a,len));
        return len;
    }

现在这很完美,但是当我进行一些数学计算时,你会得到双精度数的轻微错误:我将 10 除以 cos(60),即 0,5。答案应该是 20.0,但程序给出了 20.000000000000004(这个数字,我复制了它)。我的 while 循环卡住了,程序挂起。

有什么想法吗? (或其他检查数字位数的绝佳解决方案!)

【问题讨论】:

  • 双精度不能超过 17 位,所以当你达到 17 时你应该停止。你遇到的另一个问题是双精度可能超过 Integer.MAX_VALUE 这将导致你的第一个循环无限迭代。

标签: java floating-point count double digits


【解决方案1】:

双数和浮点数以及当时的运算并不精确,因此与代数计算相比,总会有轻微的错误。如果您使用余弦等,那么您将始终必须处理任何有关数值分析的书籍或网络文本都应描述的舍入误差。如果您使用简单的算术运算,请查看java.lang.BigDecimal

有关如何存储浮点值的详细信息。请参阅What Every Computer Scientist Should Know About Floating-Point Arithmetic

【讨论】:

    【解决方案2】:

    toString().length() 应该解决它
    记得减去'.'如果它在那里并且不应该被计算在内

    【讨论】:

    • +1 ,但不应该是 toString.length - 1 (因为这一点)?
    • @Kai:我在回答中提到了这个(第二行)
    【解决方案3】:

    这就是我实现我的方式,当双精度为大返回字符串时,简单转换为字符串,返回指数表示。即 20000000 将返回 2.0E+7,然后拆分将从此处拆分它,导致计数错误。我曾经使用BigDecimaltoPlainString() 方法

    protected int countDecimalDigits(Double d) {
        BigDecimal deci = BigDecimal.valueOf(d);
        int integerPlaces = 0;
        int decimalPlaces = 0;
        String text = deci.toPlainString();
    
        String[] integerDecimalSplit = text.split("\\.");
        if (null != integerDecimalSplit[0]) {
            integerPlaces = integerDecimalSplit[0].length();
        }
        if (integerDecimalSplit.length > 1) {
            decimalPlaces = integerDecimalSplit[1].length();
        }
        return integerPlaces + decimalPlaces;
    }
    

    【讨论】:

      【解决方案4】:

      这是一个四舍五入的问题。我会使用字符串,计算字符数,然后决定哪些数字是重要的。

      【讨论】:

        猜你喜欢
        • 2012-02-26
        • 2020-01-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-02-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多