Http://edu.eoe.cn/online classroom
Yesterday I saw a post about a few simple floating-point operations, and the computer would be wrong.
Let me introduce it to you :'
RunCode:
System. Out. println (0.05 + 0.01); System. Out. println (1.0-0.42); System. Out. println (4.015*100); System. Out. println (123.3/100 );
You can create a new project by yourself. The result is as follows:
0.06000000000000000000050.5800000000000001401.499999999999941.200009999999999999
This is amazing. 0.05 + 0.01 is obviously 0.06, but why is it 0.060000000000000005?
Is the calculator too mentally retarded? Is it true that the computer is unreliable?
Of course not.This is mainly because the simple type in Java is not suitable for exact floating point calculation. Not only Java, but other languages also have the same problem.
Although the CPU now supports floating-point operations, when the CPU is processing, it first converts a floating-point number (float, double) into an integer and then binary, and then performs operations, there are different methods for obtaining the remainder.
After the computation is completed, it is necessary to convert multiple binary values to the upper floating point. This leads to a simple and obvious error.
Therefore, float and double are generally used for scientific or engineering computing. BCD code or Java. Math. bigdecimal is usually used in areas with high precision requirements (such as commercial.
BSD code (Binary-coded decimal)BCD or binary decimal code, also known as binary decimal number. It is a binary digital encoding format that uses binary-encoded decimal code.
If you are interested in this, you can take a deeper look. Today we are mainly talking about the bigdecimal class. This is because when we are working on projects, especially for commercial projects, we cannot create any BSD code. We can directly use the bigdecimal class to fulfill our needs.
Bigdecimal is an unchangeable, any-precision, and signed decimal number provided by Java. If you want to learn more about bigdecimal, you can view the JDK documentation on your own.
Bigdecimal provides a series of constructors for converting double and string objects to bigdecimal objects.
Bigdecimal (DoubleVal)DoubleConvert to bigdecimal, which isDoubleIn decimal format. Bigdecimal (string Val) converts the string representation of bigdecimal to bigdecimal.
Traditionally, when we use floating point numbers, we define the double and float data types directly, which is no problem in definition. However, if we call the bigdecimal (double Val) method directly for conversion, note the detailed descriptions of this structure in the JDK document:
Now you can go directly to Chinese. If the English is good, you can view the original version:
Note:
The results of this constructor are unpredictable. Some people may think that the bigdecimal created by writing new bigdecimal (0.1) in Java is exactly equal to 0.1 (the non-standard degree value 1, its scale is 1), but it is actually equal to 0.1000000000000000055511151231257827021181583404541015625. This is because 0.1 cannot be accurately expressed as a double (or in this case, it cannot be expressed as any binary decimal with a limited length ). In this way, the value passed into the constructor is not exactly equal to 0.1 (although it is equal to this value on the surface ).
Bigdecimal (double Val) is unpredictable, so we recommend using bigdecimal (string Val ).
The string constructor is predictable. The new bigdecimal (". 1") is exactly equal to. 1 as expected.
Next, let's modify 0.05 + 0.01 again:
Bigdecimal bd1 =NewBigdecimal (double. tostring (0.05)); Bigdecimal bd2=NewBigdecimal (double. tostring (0.01)); System. Out. println (bd1.add (bd2 ));
Let's take a look at the running results:
0.06
This is what we want, and we have completed a high-precision operation.
Note:
Now we know how to solve this problem. In principle, we recommend using the bigdecimal (string Val) constructor.
I suggest that in commercial applications, all floating-point operations involving money are defined as string and saved in the database as string. When you need to use this money for computation, we can convert string to bigdecimal to complete high-precision computation.
Imagine if we want to do an addition operation, we need to convert two floating point numbers into strings, and then convert them into bigdecimal. Call the add method on one of them and input another as the parameter, then convert the result of the operation (bigdecimal) to a floating point number. Can you endure this cumbersome process?
So, a good tool class is found on the internet, and simple operations are closed. For more information, see:
/** ** Because Java's simple types cannot accurately perform floating-point operations, this tool class provides ** exact floating-point operations, including addition, subtraction, multiplication, division, and rounding. ** */ Public Class Arith { // Default division accuracy Private Static Final Int Def_scale = 10 ; // This class cannot be instantiated. Private Arith (){} /** * Provides precise addition operations. * @ Param V1 increment * @ Param V2 addition * @ Return The sum of the two parameters */ Public Static Double Add ( Double V1, Double V2) {bigdecimal B1 = New Bigdecimal (double. tostring (V1); bigdecimal B2 = New Bigdecimal (double. tostring (V2 )); Return B1.add (B2). doublevalue ();} /** * Provides precise subtraction operations. * @ Param V1 subtrahend * @ Param V2 subtraction * @ Return Difference between two parameters */ Public Static Double Sub ( Double V1, Double V2) {bigdecimal B1 =New Bigdecimal (double. tostring (V1); bigdecimal B2 = New Bigdecimal (double. tostring (V2 )); Return B1.subtract (B2). doublevalue ();} /** * Provides precise multiplication. * @ Param V1 multiplier * @ Param V2 multiplier * @ Return Product of Two Parameters */ Public Static Double Mul ( Double V1, Double V2) {bigdecimal B1 = New Bigdecimal (double. tostring (V1); bigdecimal B2 = New Bigdecimal (double. tostring (V2 )); Return B1.multiply (B2). doublevalue ();} /** * Provides (relatively) accurate Division operations. When division is not complete, it is accurate to * 10 digits after the decimal point, and the digits after the decimal point are rounded down. * @ Param V1 divisor * @ Param V2 divisor * @ Return Vendors of Two Parameters */ Public Static Double Div ( Double V1, Double V2 ){ Return Div (V1, V2, def_scale );} /** * Provides (relatively) accurate Division operations. In case of division, the scale parameter determines * the precision, and the number is rounded down. * @ Param V1 divisor * @ Param V2 divisor * @ Param Scale indicates the number of digits after the decimal point. * @ Return Vendors of Two Parameters */ Public Static Double Div ( Double V1, Double V2, Int Scale ){ If (Scale <0 ){ Throw New Illegalargumentexception ( "The scale must be a positive integer or zero" );} Bigdecimal B1 = New Bigdecimal (double. tostring (V1); bigdecimal B2 =New Bigdecimal (double. tostring (V2 )); Return B1.divide (B2, scale, bigdecimal. round_half_up). doublevalue ();} /** * Provides precise rounding of decimal places. * @ Param V: Number rounded up * @ Param Number of decimal places after scale * @ Return Result After rounding */ Public Static Double Round ( Double V, Int Scale ){ If (Scale <0 ){ Throw New Illegalargumentexception ( "The scale must be a positive integer or zero" );} Bigdecimal B = New Bigdecimal (double. tostring (v); bigdecimal one = New Bigdecimal ("1" ); Return B. Divide (one, scale, bigdecimal. round_half_up). doublevalue ();}}
Starting address: http://www.eoeandroid.com/thread-230579-1-1.html
Another address: http://krislq.com/150 Ga!