Java: Как установить точность для двойного значения?
Недавно я работал с номерами, и у меня была ситуация, когда я хочу установить точность двойного значения, например, 6 цифр или 4 цифры, в зависимости от значения, хранящегося в базе данных.
Например, если в базе данных точность установлена как 4 цифры, то вывод должен выглядеть так:
10.0000
.
Я пробовал с помощью DecimalFormat
и использовал строку ##.####
, но раздражает использование символов каждый раз.
Есть ли лучший подход, скажите что-то вроде ниже:
Double value = 10.0;
value.setPrecision(4);
Ответы
Ответ 1
Вы не можете установить точность двойного (или двойного) значения на указанное число десятичных цифр, поскольку значения с плавающей запятой не имеют десятичных цифр. У них есть двоичные цифры.
Вам придется преобразовать в десятичный радикс либо через BigDecimal
, либо DecimalFormat
, в зависимости от того, что вы хотите сделать со значением позже.
См. также мой ответ на этот вопрос для опровержения неизбежных ответов * 100/100.
Ответ 2
Вы можете попробовать BigDecimal для этой цели
Double toBeTruncated = new Double("3.5789055");
Double truncatedDouble = BigDecimal.valueOf(toBeTruncated)
.setScale(3, RoundingMode.HALF_UP)
.doubleValue();
Ответ 3
Это простой способ сделать это:
String formato = String.format("%.2f");
Он устанавливает точность до 2 цифр.
Если вы хотите печатать, используйте это так:
System.out.printf("%.2f",123.234);
Ответ 4
Чтобы установить точность для двойных значений DecimalFormat
, это хорошая техника. Чтобы использовать этот класс import java.text.DecimalFormat
и создать его объект, например
double no=12.786;
DecimalFormat dec = new DecimalFormat("#0.00");
System.out.println(dec.format(no));
Таким образом, он будет печатать две цифры после десятичной точки здесь, он будет печатать 12.79
Ответ 5
Это сработало для меня:
public static void main(String[] s) {
Double d = Math.PI;
d = Double.parseDouble(String.format("%.3f", d)); // can be required precision
System.out.println(d);
}
Ответ 6
Точность double
и float
фиксируется их размером и способом реализации типов с плавающей точкой IEEE.
Число десятичных цифр на выходе, с другой стороны, является вопросом форматирования. Вы правы, что вводить одну и ту же константу снова и снова - плохая идея. Вместо этого вы должны объявить строчную константу и использовать ее символическое представление.
private static final String DBL_FMT = "##.####";
Использование символического представления позволит вам изменять точность во всех местах, где константа используется без поиска через ваш код.
Ответ 7
Здесь эффективный способ достижения результата с двумя оговорками.
- Ограничивает точность до "максимальных" N цифр (не фиксируется на N цифр).
- Развертывает число (не округленное до ближайшего).
См. примеры тестов.
123.12345678 ==> 123.123
1.230000 ==> 1.23
1.1 ==> 1.1
1 ==> 1.0
0.000 ==> 0.0
0.00 ==> 0.0
0.4 ==> 0.4
0 ==> 0.0
1.4999 ==> 1.499
1.4995 ==> 1.499
1.4994 ==> 1.499
Вот код. Два оговорки, о которых я говорил выше, могут быть решены довольно легко, однако скорость важна для меня больше, чем точность, поэтому я оставил ее здесь.
Строковые манипуляции типа System.out.printf("%.2f",123.234);
являются вычислительно дорогостоящими по сравнению с математическими операциями. В моих тестах приведенный ниже код (без sysout) занял 1/30-е время по сравнению с манипуляциями с строками.
public double limitPrecision(String dblAsString, int maxDigitsAfterDecimal) {
int multiplier = (int) Math.pow(10, maxDigitsAfterDecimal);
double truncated = (double) ((long) ((Double.parseDouble(dblAsString)) * multiplier)) / multiplier;
System.out.println(dblAsString + " ==> " + truncated);
return truncated;
}
Ответ 8
BigDecimal value = new BigDecimal(10.0000);
value.setScale(4);
Ответ 9
Чтобы расширить на @EJP, понятие "точность" при работе с двойниками чрезвычайно чревато. Как обсуждалось в fooobar.com/questions/7768/..., вы даже не можете представить 0,1 как двойную, независимо от точности, по той же причине вы не можете представить 1/3 в базе 10 с конечной точностью.
Вам нужно рассмотреть проблему, которую вы пытаетесь решить, и подумайте:
a) Должен ли я использовать двойники в первую очередь; если точность является релевантной концепцией, то использование удвоений вполне может быть ошибкой.
b) Если двойники подходят, что я имею в виду под точностью? Если вы говорите только о дисплее, оберните логику в функцию отображения, и вам нужно будет только разобраться с ней в одном месте; то есть. применяйте принцип DRY.
Ответ 10
public static String setPrecision(String number, int decimal) {
double nbr = Double.valueOf(number);
int integer_Part = (int) nbr;
double float_Part = nbr - integer_Part;
int floating_point = (int) (Math.pow(10, decimal) * float_Part);
String final_nbr = String.valueOf(integer_Part) + "." + String.valueOf(floating_point);
return final_nbr;
}
Ответ 11
Возможно, этот метод поможет вам для получения двойных значений.
double truncate(double number)
{
int integerPart = (int) number;
double fractionalPart = number - integerPart;
fractionalPart *= 100; //It is for upto two decimal values after point.
//You can increase the zeros to fulfill your needs.
int fractPart = (int) fractionalPart;
fractionalPart = (double) (integerPart) + (double) (fractPart)/100;
return fractionalPart;
}
Этот метод позволит установить уровень точности.
double truncate(double number, int precision)
{
double prec = Math.pow(10, precision);
int integerPart = (int) number;
double fractionalPart = number - integerPart;
fractionalPart *= prec;
int fractPart = (int) fractionalPart;
fractionalPart = (double) (integerPart) + (double) (fractPart)/prec;
return fractionalPart;
}
Ответ 12
Я видел ответ сверху:
Double toBeTruncated = new Double("3.5789055");
Double truncatedDouble = BigDecimal.valueOf(toBeTruncated)
.setScale(3, RoundingMode.HALF_UP)
.doubleValue();
что я думаю, не является идеальным ответом, потому что ответ изменится, когда вы вызываете doubleValue()
во многих случаях.
Пример: вывод BigDecimal.valueOf(toBeTruncated).setScale(3, RoundingMode.HALF_UP)
равен 12.500,
затем после .doubleValue()
вывод будет 12,5, то есть точность теряется.
Решение: либо используйте тип BigDecimal
без .doubleValue()
для отображения, либо используйте форматирование строки после окончательного ответа.