Как округлить 0,745 до 0,75, используя BigDecimal.ROUND_HALF_UP?
114613 просмотра
5 ответа
Я попробовал следующее,
double doubleVal = 1.745;
double doubleVal1 = 0.745;
BigDecimal bdTest = new BigDecimal( doubleVal);
BigDecimal bdTest1 = new BigDecimal( doubleVal1 );
bdTest = bdTest.setScale(2, BigDecimal.ROUND_HALF_UP);
bdTest1 = bdTest1.setScale(2, BigDecimal.ROUND_HALF_UP);
System.out.println("bdTest:"+bdTest); //1.75
System.out.println("bdTest1:"+bdTest1);//0.74 problemmmm ????????????
но получил странные результаты. Почему?
Автор: aliplane Источник Размещён: 12.11.2019 09:48Ответы (5)
89 плюса
Никогда не создавайте BigDecimals из чисел с плавающей точкой или двойных. Построить их из целых или строк. плавает и удваивает потерю точности.
Этот код работает как ожидалось (я только что изменил тип с double на String):
public static void main(String[] args) {
String doubleVal = "1.745";
String doubleVal1 = "0.745";
BigDecimal bdTest = new BigDecimal( doubleVal);
BigDecimal bdTest1 = new BigDecimal( doubleVal1 );
bdTest = bdTest.setScale(2, BigDecimal.ROUND_HALF_UP);
bdTest1 = bdTest1.setScale(2, BigDecimal.ROUND_HALF_UP);
System.out.println("bdTest:"+bdTest); //1.75
System.out.println("bdTest1:"+bdTest1);//0.75, no problem
}
Автор: Augusto
Размещён: 17.09.2012 01:45
11 плюса
double doubleVal = 1.745;
double doubleVal1 = 0.745;
System.out.println(new BigDecimal(doubleVal));
System.out.println(new BigDecimal(doubleVal1));
выходы:
1.74500000000000010658141036401502788066864013671875
0.74499999999999999555910790149937383830547332763671875
Который показывает реальное значение двух двойных и объясняет полученный результат. Как отмечают другие, не используйте конструктор double (кроме конкретного случая, когда вы хотите увидеть фактическое значение double).
Подробнее о двойной точности:
Автор: assylias Размещён: 17.09.2012 01:4810 плюса
Используйте BigDecimal.valueOf(double d)
вместо new BigDecimal(double d)
. Последний имеет ошибки точности по плавающей и двойной.
2 плюса
Это может дать вам подсказку о том, что пошло не так.
import java.math.BigDecimal;
public class Main {
public static void main(String[] args) {
BigDecimal bdTest = new BigDecimal(0.745);
BigDecimal bdTest1 = new BigDecimal("0.745");
bdTest = bdTest.setScale(2, BigDecimal.ROUND_HALF_UP);
bdTest1 = bdTest1.setScale(2, BigDecimal.ROUND_HALF_UP);
System.out.println("bdTest:" + bdTest);
System.out.println("bdTest1:" + bdTest1);
}
}
Проблема в том, что ваш вход (а double x=0.745;
) не может точно представлять 0,745. Это на самом деле сохраняет значение немного ниже. Ибо BigDecimals
это уже ниже 0,745, поэтому он округляется вниз ...
Старайтесь не использовать BigDecimal(double/float)
конструкторы.
2 плюса
Для вашего интереса, сделать то же самое с double
double doubleVal = 1.745;
double doubleVal2 = 0.745;
doubleVal = Math.round(doubleVal * 100 + 0.005) / 100.0;
doubleVal2 = Math.round(doubleVal2 * 100 + 0.005) / 100.0;
System.out.println("bdTest: " + doubleVal); //1.75
System.out.println("bdTest1: " + doubleVal2);//0.75
или просто
double doubleVal = 1.745;
double doubleVal2 = 0.745;
System.out.printf("bdTest: %.2f%n", doubleVal);
System.out.printf("bdTest1: %.2f%n", doubleVal2);
обе печати
bdTest: 1.75
bdTest1: 0.75
Я предпочитаю сделать код максимально простым. ;)
Как отмечает @mshutov, вам нужно добавить немного больше, чтобы половина значений всегда округлялась. Это потому, что числа вроде 265.335
немного меньше, чем кажутся.
Вопросы из категории :
- java В чем разница между int и Integer в Java и C #?
- java Как я могу определить IP моего маршрутизатора / шлюза в Java?
- java Каков наилучший способ проверки XML-файла по сравнению с XSD-файлом?
- java Как округлить результат целочисленного деления?
- java Преобразование списка <Integer> в список <String>
- java Почему я не могу объявить статические методы в интерфейсе?
- bigdecimal «new BigDecimal (13.3D)» приводит к неточности «13.3000000000000007105 ..»?
- bigdecimal Использование BigDecimal для работы с валютами
- bigdecimal Дополнение для BigDecimal
- bigdecimal Java BigDecimal использование памяти?
- bigdecimal Лучшая кроссплатформенная (портативная) математическая библиотека произвольной точности
- bigdecimal Что эквивалентно классу Java BigDecimal в C #?
- rounding Усеченные (не круглые) десятичные знаки в SQL Server
- rounding Как округлить число до n знаков после запятой в Java
- rounding How do I round a decimal value to 2 decimal places (for output on a page)
- rounding Как округлить число до двух десятичных знаков в C #?
- rounding Должен ли я использовать NSDecimalNumber, чтобы иметь дело с деньгами?
- rounding Ограничение числа с плавающей точкой до двух десятичных знаков