Проблема с получением цифр в двойной переменной
-
13-11-2019 - |
Вопрос
У меня возникла небольшая проблема с функцией, которая мне нужна в моей 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 застревает, и программа зависает.
Есть идеи?(Или другие отличные решения для проверки цифр числа!)
Решение
Удвоение и поплавки и эксплуатации на потом не точны, поэтому всегда будут незначительные ошибки по сравнению с алгебраическими расчетами.Если вы используете Coysines etc, то вам всегда нужно будет иметь дело с этими ошибками округления, которые должны описывать любую книгу или веб-текст по численному анализу.Если вы используете простые аритметические операции, посмотрите на java.lang.BigDecimal
Для получения подробной информации о том, как хранятся значения с плавающей запятой. Что каждый компьютерный ученый должен знать о арифметике с плавающей точкой
Другие советы
TOSTRING (). Длина () должна решить ее
Вот как я реализовал свое: простое преобразование в строку, когда двойное значение было слишком большим, возвращаемая строка с экспоненциальным представлением.т.е. 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;
}
Это проблема округления.Я бы использовал строки, сосчитать персонажей и решить, какие цифры должны быть подсчитаны значительными.