Извлечение целой и дробной части из Bigdecimal в Java

Я хочу извлечь целочисленную часть и десятичную часть из bigdecimal в java.

для этого я использую следующий код.

    BigDecimal bd = BigDecimal.valueOf(-1.30)
    String textBD = bd.toPlainString();
    System.out.println("length = "+textBD.length());
    int radixLoc = textBD.indexOf('.');
    System.out.println("Fraction "+textBD.substring(0,radixLoc)+"Cents: " + textBD.substring(radixLoc + 1, textBD.length()));

Я получаю вывод как

-1 и 3

но я хочу, чтобы трейлинг-ноль и от -1.30

выход должен быть!--8-->-1 и 30

3 ответов


представление с плавающей запятой -1.30 не является точным. Вот небольшая модификация вашего кода:

BigDecimal bd = new BigDecimal("-1.30").setScale(2, RoundingMode.HALF_UP);
String textBD = bd.toPlainString();
System.out.println("text version, length = <" + textBD + ">, " + textBD.length());
int radixLoc = textBD.indexOf('.');
System.out.println("Fraction " + textBD.substring(0, radixLoc)
    + ". Cents: " + textBD.substring(radixLoc + 1, textBD.length()));

Я поставил RoundingMode на setScale для округления дробных Пенни, таких как 1.295 "половина вверх" до 1.30.

результаты:

text version, length = <-1.30>, 5
Fraction -1. Cents: 30

Если вам нравится не связываться со строками (что, я думаю, не очень хорошая практика - кроме части создания де BigDecimal), вы можете сделать это только с помощью Math:

// [1] Creating and rounding (just like GriffeyDog suggested) so you can sure scale are 2
BigDecimal bd = new BigDecimal("-1.30").setScale(2, RoundingMode.HALF_UP);

// [2] Fraction part (0.30)
BigDecimal fraction = bd.remainder(BigDecimal.ONE);

// [3] Fraction as integer - move the decimal.
BigDecimal fraction2 = fraction.movePointRight(bd.scale());

// [4] And the Integer part can result of:
BigDecimal natural = bd.subtract(fraction);

// [5] Since the fraction part of 'natural' is just Zeros, you can setScale(0) without worry about rounding
natural = natural.setScale(0);

инициализации с String чтобы избежать проблем с точностью с плавающей запятой. Тогда используйте setScale чтобы установить желаемое количество десятичных знаков:

BigDecimal bd = new BigDecimal("-1.30").setScale(2);
String textBD = bd.toPlainString();
System.out.println("length = "+textBD.length());
int radixLoc = textBD.indexOf('.');
System.out.println("Fraction "+textBD.substring(0,radixLoc)+"Cents: " + textBD.substring(radixLoc + 1, textBD.length()));