Działania na BigDecimal

0

Mam taki kawałek kodu:

  BigDecimal year = new BigDecimal(12);

  return estimatedSavingsInYearScale
                .divide(year, 2, BigDecimal.ROUND_HALF_UP)
                .multiply(proposalContractMonthLength);
 

Gdzie jeśli np. estimatedSavingsInYearScale jest równy 16854.20 a proposalContractMonthLength jest równy 12,
to mój wynik jest równych 16854.16.

W jaki sposób podejść do tego aby wyjściowa liczba pozostała bez zmian ?

3

Możesz najpierw pomnożyć, a potem podzielić i problem zaokrąglenia zniknie.

0

Niepotrzebnie zaokrąglasz wynik dzielenia do dwóch miejsc po przecinku.

0

@bogdans

Zaokrąglam ponieważ chcę zaprezentować wynik do dwóch miejsc po przecinku. Jak podejść inaczej do tego ?

0

Mam podobne działania które mają o wiele więcej dzielenia i mnożenia. Tam jak porównam wynik do tego co excel liczy to są znaczne różnice...

2

Jak podejść inaczej do tego?
Nie możesz zaokrąglać wyników pośrednich. Końcowych też nie powinieneś, ogranicz się do sformatowania wypisywanych wyników.

0

Skoro nie potrzebujesz dużej dokładności, to dlaczego korzystasz z typu BigDecimal?

0

Potrzebuję dużej precyzji ale jednocześnie chcę prezentować wyniki tylko do dwóch miejsc po przecinku. Co więcej chciał bym przed wysłaniem do widoku już dokonać zaaokrągelnia.

1

BigDecimal jest immutable, więc każda operacja zwraca nowy obiekt. Zatem to:

new BigDecimal(9).divide(new BigDecimal(2), BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(2))

działa tak, że 9/2 zawraca 5, a kolejnym działaniem jest 5*2, co daje 10 zamiast oczekiwanego 9. Tak, jak już napisano - nie zaokrąglaj w trakcie liczenia.

Poza tym, używasz konstruktora BigDecimal z doublem zamiast ze Stringiem, więc też tracisz precyzję. Porównaj:

BigDecimal highPrecisionVal1 = new BigDecimal("3");
BigDecimal highPrecisionVal2 = new BigDecimal("0.1");

BigDecimal lowPrecisionVal1 = new BigDecimal(0.3);
BigDecimal lowPrecisionVal2 = new BigDecimal(0.1);

System.out.println(highPrecisionVal1.multiply(highPrecisionVal2));
System.out.println(lowPrecisionVal1.multiply(lowPrecisionVal2));
0
bogdans napisał(a):

Jak podejść inaczej do tego?
Nie możesz zaokrąglać wyników pośrednich. Końcowych też nie powinieneś, ogranicz się do sformatowania wypisywanych wyników.

jak z pomocą BigDecimal bez zaokrąglenia zrobisz 1/3 to poleci exception ArithmeticException.
https://docs.oracle.com/javase/7/docs/api/java/math/BigDecimal.html#divide(java.math.BigDecimal)

0

Hm, racja. To wtedy poratuje odpowiednio duży parametr scale przy dzieleniu.

1 użytkowników online, w tym zalogowanych: 0, gości: 1