Проблема получения цифр в двойной переменной - PullRequest
4 голосов
/ 13 мая 2011

У меня небольшая проблема с функцией, которая мне нужна в моей Java-программе. Я хочу проверить общее количество цифр, которое есть в переменной типа double. (например: 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 зависает, и программа зависает.

Есть идеи? (Или другие отличные решения для проверки цифр числа!)

Ответы [ 4 ]

3 голосов
/ 13 мая 2011

Двойные и плавающие числа и операции над ними не являются точными, поэтому всегда будут небольшие ошибки по сравнению с алгебраическими вычислениями.Если вы используете косинусы и т. Д., Вам всегда придется иметь дело с этими ошибками округления, которые должна описывать любая книга или веб-текст о численном анализе.Если вы используете простые арифметические операции, посмотрите java.lang.BigDecimal

Подробнее о том, как хранятся значения с плавающей запятой. См. Что должен знать каждый компьютерный ученый о числах с плавающей запятойАрифметика

1 голос
/ 20 апреля 2015

Так я реализовал простое преобразование в String, когда значение типа double было большим, возвращало String с экспоненциальным представлением.т. е. 20000000 вернет 2.0E + 7, а затем разделение разделит его отсюда, что приведет к неправильному счету.Я привык к BigDecimal и toPlainString() метод

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;
}
1 голос
/ 13 мая 2011

toString (). Length () должен решить это
помните, чтобы вычесть «.» если оно есть и не должно учитываться

0 голосов
/ 13 мая 2011

Это вопрос округления. Я бы использовал Strings, посчитал символы и решил, какие цифры считать значительными.

...