BigDecimal explained

A BigDecimal consists of an arbitrary-precision integer unscaled value and a 32-bit integer scale. If zero or positive, the scale is the number of digits after the decimal point. If negative, the unscaled value of the number is multiplied by 10 to the negative scale power. Therefore, the value represented by BigDecimal is (unscaledValue × 10-scale).

Can handle floating point arithmetic of arbitrary length.

BigDecimal add(BigDecimal val) //BigDecimal addition

BigDecimal subtract (BigDecimal val) //BigDecimal subtraction

BigDecimal multiply (BigDecimal val) //BigDecimal multiplication

BigDecimal divide (BigDecimal val,RoundingMode mode) Division


Specific use of calculation:

  
  Add: a.add( b);

  Subtract: a.subtract(b);

  Multiply: a.multiply(b); Division

  : a.divide(b,2);//2 is the precision   value Throwing an exception, reason: When dividing by BigDecimal's divide method, it will not be divided, and an infinite loop of decimals will be thrown.          //BigDecimal divideBg = a.divide(b);           //The solution is: set the precision; is to set an exact decimal point for divide




divide(xxxxx,2, BigDecimal.ROUND_HALF_EVEN)  
        //The second parameter indicates: how many digits after the decimal point are reserved for 

BigDecimal not to divide the thrown exception, please set the precision!
Exception in thread "main" java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.
at java.math.BigDecimal.divide(BigDecimal.java:1278)
at main.Main.main(Main.java: 41)

Let's take a look at the detailed description of division:
   divide(BigDecimal divisor, int scale, introundingMode)


BigDecimal's setScale method The

BigDecimal.setScale()

method is used to format the decimal point to

indicate that one decimal place is reserved, and the default rounding method is

setScale(1 )

directly delete the extra decimal places, such as 2.35 will become 2.3 setScale(1, BigDecimal.ROUND_DOWN)

carry processing, 2.35 will become 2.4 setScale(1, BigDecimal.ROUND_UP)

Rounding, 2.35 becomes 2.4 setScale(1, BigDecimal.ROUND_HALF_UP)

rounding, 2.35 becomes 2.3, if it is 5, it is rounded down setScaler(1, BigDecimal.ROUND_HALF_DOWN)

 
Note that

scale refers to the number of digits after your decimal point.
scale() is the method in the BigDecimal class. For example

, BigDecimal b = new BigDecimal("123.456");

b.scale() returns 3.
Note that the second roundingMode is the reserved mode of decimals. They are all constant fields in BigDecimal,

there are many kinds, such as
BigDecimal.ROUND_HALF_UP means 4 rounding 5.

Note that point 3

divide (BigDecimal divisor, int scale, introundingMode) means:
I divide a BigDecimal object by divisor After the result, and the result is required to retain scale decimal places, roundingMode indicates what the retention mode is, whether it is rounding or other


BigDecimal aa = new BigDecimal(135.95 ); 

BigDecimal bb=new BigDecimal("100" ); 

BigDecimal result=aa.multiply(bb); //do addition



3. The BigDecimal type in java can be converted to double type:
  use the variable .doubleValue(); function to convert BigDecimal type data to double type!
4.java BigDecimal compares the size

You can by the compareTo method of BigDecimal.
The returned result is of type int, -1 means less than, 0 is equal, and 1 is greater than.

Look at the following example:
BigDecimal a = new BigDecimal("1.00");
BigDecmial b = new BigDecimal(1);

To compare the size of a and b, use equals

System.out.println(a.equals(b) );
but the output is: false The
reason is: when comparing BigDecimal, not only the value, but also the precision?


The result of if(a.compareTo(b)==0) is true

. The comparison size can be used a.compareTo(b)
to return the value -1 is less than 0, equal to 1 and greater than

5. BigDecimal takes the maximum, minimum, absolute value and opposite number:

  a.max (b) //Compare to take the maximum value

  a.min(b) //Compare to take the minimum value

  a.abs()//Take the absolute value

  a.negate()//Take the opposite number


6. The following is the note :

BigDecimal enum constant usage summary:

CEILING  
          rounding mode for rounding towards positive infinity.
DOWN  
          Rounding mode for rounding towards zero.
FLOOR  
          Rounding mode for rounding towards negative infinity.
HALF_DOWN  
          A rounding mode for rounding toward the nearest digit, or down if it is equidistant from two adjacent digits.
HALF_EVEN  
          Rounding mode for rounding towards the nearest digit, if it is equidistant from two adjacent digits, rounding towards the adjacent even digit.
HALF_UP  
          Rounding mode for rounding toward the nearest number, or up if the distance from two adjacent numbers is equal.
UNNECESSARY  
          is used to assert that the requested operation has the rounding mode of the exact result, so no rounding is required.
UP  
          Rounding mode for rounding away from zero.



7. About BigDecimal formatting

public String formatValue(Object value){
        String content = null;
        if (value == null) {
             content = "";
         } else {
             if(value instanceof BigDecimal){
                 //conver to fortmat String
                 NumberFormat nf = NumberFormat.getInstance();
                 nf.setMinimumFractionDigits(2);
                 nf.setMaximumFractionDigits(2);
                 content = nf.format(value); 
             }else {
                 content = String.valueOf(value);
             }
         }
        return content;
    }

Using such a method can achieve the effect of formatting, where value instanceof BigDecimal indicates that the character type is executed when the character type is BigDecimal type, and NumberFormat here indicates the character Type, the following two lines of code indicate the exact number of digits after the decimal point.

There are also two other types of NumberFormat mentioned here:

getCurrencyInstance(): Returns the currency format of the current default environment

CurrencyInstance(): Returns the numeric format of the specified locale, generally in percentage format


8. This principle is also mentioned in the book "Effective Java", float and double can only be used for scientific or engineering calculations. In the calculation we use java.math.BigDecimal.
If we need accurate calculation, we must use String to create BigDecimal!

The following tool class is reproduced by others, and can achieve accurate calculation of decimals through a tool class.

1import java.math.BigDecimal;  
2/** *//** 
3* Since Java's simple types cannot perform precise operations on floating-point numbers, this utility class provides precise 
4* operations on floating-point numbers, including addition, subtraction, multiplication and division and rounding up. 
5*/ 
6public class Arith{  
7 //Default division precision  
8 private static final int DEF_DIV_SCALE = 10;  
9 //This class cannot be instantiated  
10 private Arith(){  
11 }  
12 
13 /** *//** 
14 * Provides exact addition operations. 
15 * @param v1 summand 
16 * @param v2 summand 
17 * @return the sum of the two parameters 
18 */ 
19 public static double add(double v1, double v2){  
20 BigDecimal b1 = new BigDecimal(Double.toString(v1));  
21 BigDecimal b2 = new BigDecimal(Double.toString (v2));  
22 return b1.add(b2).doubleValue();  
23 }  
24 /** *//** 
25 * Provides exact subtraction. 
26 * @param v1 Minuend 
27 * @param v2 Minuend 
28 * @return Difference of two parameters 
29 */ 
30 public static double sub(double v1,double v2){  
31 BigDecimal b1 = new BigDecimal(Double.toString (v1));  
32 BigDecimal b2 = new BigDecimal(Double.toString(v2));  
33 return b1.subtract(b2).doubleValue();  
34 }   
35 /** *//** 
36 * Provides exact multiplication. 
37 * @param v1 multiplicand 
38 * @param v2 multiplier 
39 * @return the product of two parameters 
40 */ 
41 public static double mul(double v1,double v2){  
42 BigDecimal b1 = new BigDecimal(Double.toString (v1));  
43 BigDecimal b2 = new BigDecimal(Double.toString(v2));  
44 return b1.multiply(b2).doubleValue();  
45 }  
46 
47 /** *//** 
48 * provide (relative ) exact division operation, when there is an inexhaustible division, it is accurate to 
49 * 10 digits after the decimal point, and the following digits are rounded up. 
50 * @param v1 dividend 
51 * @param v2 divisor 
52 * @return the quotient of two parameters 
53 */ 
54 public static double div(double v1,double v2){  
55 return div(v1,v2,DEF_DIV_SCALE);  
56 }  
57 
58 /** *//** 
59 * Provides (relatively) exact division operations. When there is an inexhaustible division, the scale parameter refers to 
60 * fixed precision, and the following numbers are rounded. 
61 * @param v1 Dividend 
62 * @param v2 Divider 
63 * @param scale Indicates that it needs to be accurate to a few decimal places. 
64 * @return the quotient of two parameters 
65 */ 
66 public static double div(double v1,double v2,int scale){  
67 if(scale<0){  
68 throw new IllegalArgumentException(  
69 "The scale must be a positive integer or zero");  
70 }  
71 BigDecimal b1 = new BigDecimal(Double.toString(v1));  
72 BigDecimal b2 = new BigDecimal(Double.toString(v2));  
73 return b1.divid(b2,scale,BigDecimal.ROUND_HALF_UP).doubleValue();  
74 }  
75 
76 /** *//** 
77 * Provides accurate decimal rounding. 
78 * @param v The number to be rounded 
79 * @param scale The number of decimal places reserved 
80 * @return The rounded result 
81 */ 
82 public static double round(double v,int scale){  
83 if(scale<0) {  
84 throw new IllegalArgumentException(  
85 "The scale must be a positive integer or zero");  
86 }  
87 BigDecimal b = new BigDecimal(Double.toString(v));  
88 BigDecimal one = new BigDecimal("1");  
89 return b.divid(one,scale,BigDecimal.ROUND_HALF_UP).doubleValue();  
90 }  
91 } 


For detailed BigDecimal algorithm, please refer to http://zhenchengchagangzi.iteye.com/blog/1258453




8 rounding modes of BigDecimal in Java:

java.math.BigDecimal Immutable
, arbitrary-precision signed decimal number. BigDecimal consists of an arbitrary-precision integer unscaled value and a 32-bit integer scale.
If zero or positive, the scale is the number of digits after the decimal point. If negative, multiply the unscaled value of the number by 10 to the negative scale power.
Therefore, the value represented by BigDecimal is (unscaledValue × 10-scale).
There are also two related classes:
java.math.MathContext:
This object is an immutable object that encapsulates context settings, and it describes certain rules for numeric operators, such as the precision of data, rounding, and so on.
java.math.RoundingMode:
This is an enumeration type that defines many common ways of rounding data.
This class is quite complicated to use. The reason is the rounding mode, and there are too many data operation rules. It
is difficult for people who are not mathematics majors to understand the Chinese API. When these rules are used in practice, it is too late to read. .
BigDecimal provides precise numerical calculations in areas such as banking, accounts, billing, and more. Eight of these rounding methods are worth mastering.
1. ROUND_UP
Rounding mode for rounding away from zero.
Always increment the number before discarding the non-zero part (always add 1 to the number preceding the non-zero discard part).
Note that this rounding mode never reduces the size of the computed value. 2. Rounding mode
where ROUND_DOWN is close to zero. Never increment a number before discarding a part (never add 1 to the number preceding the discarded part, i.e. truncate). Note that this rounding mode never increases the size of the computed value. 3. ROUND_CEILING rounding mode close to positive infinity. If BigDecimal is positive, the rounding behavior is the same as ROUND_UP; if negative, the rounding behavior is the same as ROUND_DOWN. Note that this rounding mode never reduces the calculated value. 4. ROUND_FLOOR rounding mode close to negative infinity. If BigDecimal is positive, the rounding behavior is the same as ROUND_DOWN; if negative, the rounding behavior is the same as ROUND_UP. Note that this rounding mode never adds to the calculated value. 5. ROUND_HALF_UP














A rounding mode that rounds towards the "nearest" number, if it is equidistant from two adjacent numbers, then rounds up.
If the discarded portion is >= 0.5, the rounding behavior is the same as ROUND_UP; otherwise, the rounding behavior is the same as ROUND_DOWN.
Note that this is the rounding mode (rounding) that most of us were taught in elementary school.
6. ROUND_HALF_DOWN rounds
to the "closest" number, if the distance from two adjacent numbers is equal, it is the rounding mode of rounding up.
If the rounding part is > 0.5, the rounding behavior is the same as ROUND_UP; otherwise, the rounding behavior is the same as ROUND_DOWN (rounding down).
7. ROUND_HALF_EVEN rounds
to the "closest" number, and if it is equidistant from two adjacent numbers, rounds to the adjacent even number.
If the number to the left of the discarded part is odd, the rounding behavior is the same as ROUND_HALF_UP;
if it is even, the rounding behavior is the same as ROUND_HALF_DOWN.
Note that this rounding mode minimizes accumulation errors when repeating a series of calculations.
This rounding mode is also known as "Banker's Rounding" and is mainly used in the United States. Rounding up, five out of two cases.
If the previous digit is odd, it is rounded, otherwise it is rounded off.
The following example is the result of keeping 1 decimal point, then this rounding method.
1.15>1.2 1.25>1.2
8. The operation requested by the ROUND_UNNECESSARY
assertion has an exact result, so no rounding is required.
Throws an ArithmeticException if this rounding mode is specified for an operation that obtains an exact result.

Summary of rounding operations in different rounding modes Result of rounding the input number to one digit
according to the given rounding mode
Input number UP DOWN CEILING FLOOR HALF_UP HALF_DOWN HALF_EVEN UNNECESSARY
5.5 6 5 6 5 6 5 6 Throws ArithmeticException
2.5 3 2 3 2 3 2 2 Throws ArithmeticException
1.6 2 1 2 1 2 2 2 Throws ArithmeticException
1.1 2 1 2 1 1 1 1 Throws ArithmeticException
1.0 1 1 1 1 1 1 1 1
-1.0 -1 -1 -1 - 1 -1 -1 -1 -1
-1.1 -2 -1 -1 -2 -1 -1 -1 throws ArithmeticException
-1.6 -2 -1 -1 -2 -2 -2 -2 throws ArithmeticException
-2.5 - 3 -2 -2 -3 -3 -2 -2 Throws ArithmeticException
-5.5 -6 -5 -5 -6 -6 -5 -6 Throws ArithmeticException


Reprinted from:
http://zhangyinhu8680.iteye.com/blog/ 1536397
http://www.bdqn.cn/news/201311/11834.shtml








Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326684701&siteId=291194637