10 Temmuz 2019 Çarşamba

BigDecimal Sınıfı

En İyi Kullanım Şekli
1. double ile Yaratma

2. Karşılaştırma
BigDecimal  karşılaştırma için equals() ve compareTo() metodları sunuyor. Ancak aralarda fark var. compareTo() terchih edilmeli. Fark şöyle
@Test
public void testBigDecimalCompare(){
  BigDecimal a = new BigDecimal("0.01");
  BigDecimal b = new BigDecimal("0.010");
  System.out.println(a.equals(b));
  System.out.println(a.compareTo(b));
}

//false
//0
Açıklaması şöyle
the equals method not only compares whether the values are equal or not, but also whether the precision is the same.

In the above example, the result of the equals method is of course false because the precision of the two is different. The compareTo method implements the Comparable interface, which compares the size of the values and returns the values -1 (less than), 0 (equal to), and 1 (greater than).

Usually, if comparing the size of two BigDecimal values, the compareTo method is commonly used; if the comparison is strictly limited in precision, then the equals method can be considered.
3. Set Precision Before Calculation
Açıklaması şöyle
Use the correct rounding mode when performing arithmetic operations
When performing arithmetic operations on BigDecimal values, it is important to use the correct rounding mode to ensure that the result is rounded correctly. The rounding mode determines how the result is rounded when the precision of the result exceeds the precision of the original values.

There are different rounding modes to choose from, such as RoundingMode.UP, RoundingMode.DOWN, RoundingMode.HALF_UP, and RoundingMode.HALF_DOWN. The recommended rounding mode for financial calculations is RoundingMode.HALF_UP, which rounds up when the next digit is 5 or greater.
Örnek
Elimizde şöyle bir kod olsun
@Test
public void testDivide(){
  BigDecimal a = new BigDecimal("1.0");
  BigDecimal b = new BigDecimal("3.0");
  a.divide(b);
}

java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable 
decimal result.
at java.base/java.math.BigDecimal.divide(BigDecimal.java:1722)
Açıklaması şöyle. Yani sonuç sonsuz ise exception fırlatılır.
If the quotient is an infinite decimal (0.333…) during the divide operation and the result of the operation is expected to be an exact number, then an ArithmeticException will be thrown.

In this case, it is sufficient to specify the precision of the result when using the divide method.
Düzeltmek için şöyle yaparız
@Test
public void testDivide(){
  BigDecimal a = new BigDecimal("1.0");
  BigDecimal b = new BigDecimal("3.0");
  BigDecimal c = a.divide(b, 2, RoundingMode.HALF_UP);
  System.out.println(c);
}
Örnek - Finansal Hesaplama
Şöyle yaparız
BigDecimal value1 = new BigDecimal("123.456");
BigDecimal value2 = new BigDecimal("789.012");
BigDecimal result = value1.add(value2).setScale(2, RoundingMode.HALF_UP);
4. Output String
Elimizde şöyle bir kod olsun
@Test
public void testToString(){
   BigDecimal a = BigDecimal.valueOf(455535353556655555.555555555555555555);
   System.out.println(a.toString());
}

//4.5553535355665555E+17
Açıklaması şöyle
Here we need to understand the three methods of BigDecimal to string conversion:

toPlainString(): without using any scientific notation.
toString() : uses scientific notation when necessary.
toEngineeringString() : Use engineering notation when necessary. (Similar to scientific notation, except that the powers of the exponents are all multiples of 3, which makes it easier to use in engineering since in many unit conversions they are 10^3.)

constructor - double
new BigDecimal() ve BigDecimal.valueOf() Farkı  yazısına taşıdım

constructor - double + MathContext
Şöyle yaparız. Yuvarlama işlemine tabi tutar. double tam temsil edilemese bile yuvarlamak işlemine tabi tutulduğu için doğru sonucu alırız.
BigDecimal bd = new BigDecimal(0.7d, MathContext.DECIMAL32);
BigDecimal bd = new BigDecimal(0.7d, MathContext.DECIMAL64)
constructor - String
BigDecimal mümkünse string ile yaratılmalıdır. Aşağıdaki kod çıktı olarak 58.34 sayısını verir.
System.out.println (new BigDecimal ("58.34"));
String scientific notation olarak ta verilebilir. Şöyle yaparız.
BigDecimal bd = new BigDecimal ("1.00E-7"); 
Şöyle yaparız
BigDecimal bd = new BigDecimal("4.30000000e+01");
compareTo metodu
İki BigDecimal nesnesini karşılaştırır.
BigDecimal bd = new BigDecimal("12");
bd.compareTo (new BigDecimal(0));  //Returns 1
Şu şekilde bir sürü yardımcı metod kullanılabilir.
public class BigDecimalUtil {

  public static boolean isZero(BigDecimal value) {
    return value == null?false:value.compareTo(BigDecimal.ZERO) == 0;
  }   

  public static boolean isPositive(BigDecimal value) {
    return value == null?false:value.compareTo(BigDecimal.ZERO) > 0;
  }

  public static boolean isNegative(BigDecimal value) {
    return value == null?false:value.compareTo(BigDecimal.ZERO) < 0;
  }

  public static boolean isEqual(BigDecimal value1, BigDecimal value2) {
    return value1.compareTo(value2) == 0;
  }

  public static boolean isLessThan(BigDecimal value1, BigDecimal value2) {
    return value1.compareTo(value2) < 0;
  }

  public static boolean isMoreThan(BigDecimal value1, BigDecimal value2) {
    return value1.compareTo(value2) > 0;
  }
}
divide metodu
Elimizde şöyle bir işlem olsun. Eğer bölme işlemi sonsuz sayıda hane verir.
new BigDecimal("10").divide(new BigDecimal("3"))
Dolayısıyla ArithmeticException fırlatılır. Hata mesajı şöyledir
Non-terminating decimal expansion; no exact representable decimal result
Çözüm için şöyle yaparız.
new BigDecimal("10")
    .setScale(10)
    .divide(new BigDecimal("3"), BigDecimal.ROUND_HALF_EVEN)
divide metodu - BigDecimal + scale
Açıklaması şöyle
BigDecimal java.math.BigDecimal.divide(BigDecimal divisor, int roundingMode)
Returns a BigDecimal whose value is (this / divisor), and whose scale is this.scale(). If rounding must be performed to generate a result with the given scale, the specified rounding mode is applied.
divide metodu - BigDecimal + scale + rounding mode
Şöyle yaparız
BigDecimal x = new BigDecimal("4.8");
BigDecimal y = new BigDecimal("7.11");
BigDecimal z = x.divide(y, 0, RoundingMode.HALF_UP);
doubleValue metodu
Şöyle yaparız.
double myDouble = bd.doubleValue();
floatValue metodu
Şöyle yaparız.
float myFloat = bd.floatValue();
intValue metodu
Şöyle yaparız.
int myInt = bd.intValue();
negate metodu
Değer negatif sayı ise pozitif sayı, pozitif sayı ise negatif sayı yaparı. Örneğin değer 10 ise -10 yapar.

precision metodu
Açıklaması şöyle. Kaç tane hane olduğunu döndürür.
The precision is the number of digits in the unscaled value. The precision of a zero value is 1.
Şöyle yaparız.
scala> new java.math.BigDecimal("500").precision()
res0: Int = 3
Şöyle yaparız.
if(bd.precision() <= 3) {...}
round metodu
Örnek
HALF_DOWN ile en yakın sayıya yuvarlanır. Şöyle yaparız.
BigDecimal bD = new BigDecimal(5.46597); 
System.out.println(bD.round(new MathContext(3, RoundingMode.HALF_DOWN))); // 5.47
setScale metodu
Belirtilen küsürat sayısını kullanan yeni bir nesne döner. Round metoduna benzer.
Örnek
HALF_DOWN ile en yakın sayıya yuvarlanır. Şöyle yaparız.
BigDecimal bD = new BigDecimal(5.46597);
System.out.println(bD.setScale(2, RoundingMode.HALF_DOWN)); // 5.47
Örnek
BigDecimal bd = new BigDecimal ("1.01234");
System.out.println (bd.setScale(2, RoundingMode.HALF_UP));//Sonuç 1.01
stripTrailingZeros metodu
Sondaki sıfırları atılmış halde yeni bir BigDecimal nesnesi döndürür.

Örnek
Şöyle yaparız.
new BigDecimal("1.2300").stripTrailingZeros().toPlainString() 
Sonuç olarak şunu alırız.
1.23
subtract metodu
Şöyle yaparız
BigDecimal s = new BigDecimal("472.24");
BigDecimal result = s.subtract(new BigDecimal("100.0"));
System.out.println(result);
Çıktı olarak şunu alırız.
372.24
toBigInteger metodu
BigInteger nesnesine çevirir. Şöyle yaparız.
bd.toBigInteger();
toPlainString
Açıklaması şöyle. toString() metodu scientific notation çıktı verirken bu metod vermez. Nesneyi string'e çevirir.
toPlainString() - Returns a string representation of this BigDecimal without an exponent field.
Örnek
Şöyle yaparız.
BigDecimal bd = ...;
bd.toPlainString();
Örnek
Şöyle yaparız.
BigDecimal bd = new BigDecimal("1.00E-7"); 
System.out.println(bd.toPlainString());
Çıktı olarak şunu alırız.
"0.0000001"
unscaledValue metodu
Küsürat alanlarını tamsayıya dahil eder.

Örnek
Elimizdeki değer 6.54 olsun. Bu metodu çağırarak küsüratlardan kurtulup 654 değerini elde ederiz.

valueOf metodu






Hiç yorum yok:

Yorum Gönder