Currency Handling of "151 Suggestions for Improving Java Programs" Reading Notes

Recommendation 22: Handle currencies with integer types

In daily life, the most accessible decimal is currency. For example, if you pay a salesman 10 yuan to buy a
snack of 9.60 yuan, the salesperson should ask you 0.4 yuan, which is 4 cents. Let's look at the following procedure:
This document is generated by the extremely fast PDF editor.
If you want to remove this prompt, please visit and download:
http://www.jisupdfeditor.com/
2017/10/20
52/396
public class Client{
public static void main
( String[] args ) {
System.out.println
( 10.00-9.60 );
} }
We expect the result to be 0.4, which should be the same number, but it prints
0.40000000000000036, why?
This is because floating-point numbers may (note that they may) be inaccurate in computers, and they can only be infinitely close to accurate
values, not completely accurate. Why is this so? This is determined by the storage rules of floating-point numbers. Let's first look at
how the decimal fraction of 0.4 is converted into a binary fraction, using the method of "multiplying by 2 and rounding up and ordering" (do not understand? This is no
trick, it is too basic ), we found that 0.4 cannot be represented using binary exactness, in the binary world it is an
infinitely recurring decimal, that is, neither "display" can be "displayed", let alone stored in memory (floating point numbers
The storage consists of three parts: sign bit, exponent bit, and mantissa, which will not be introduced in detail). It can be understood that
there is no way to accurately represent 1/3 in the decimal world, and of course 1/5 cannot be accurately represented in the binary world. (If binary also has
fractions, it can be represented.) In the binary world, 1/5 is an infinitely recurring decimal.
Everyone wants to say, then am I right to round up the result? The code is as follows:
public class Client{
public static void main
( String[]args ) {
NumberFormat f=new DecimalFormat
( "#.##" );
System.out.println ( f.format ( 10.00-9.60 ));
} }
The printed result is 0.4, which seems to be solved, but hides a deep problem. Let's think about the calculation method in the financial
industry . The accounting system generally records 4 decimal places after the decimal point, but in summary, presentation, and reports, only
2 decimal places after the decimal point are recorded. If you use floating-point numbers to calculate currency, think Want to see how different the
results (which also involves rounding issues that will be discussed later)! The accounting system wants to be accurate,
but it is inaccurate because of the computer, and that is a sin. There are two ways to solve this problem:
(1) Use BigDecimal
This document is generated by an extremely fast PDF editor.
If you want to remove this prompt, please visit and download:
http://www.jisupdfeditor.com/
2017/10/20
53/396
BigDecimal is specially designed to make up for the shortcomings that floating-point numbers cannot be accurately calculated The class is designed, and it also provides
common mathematical algorithms for addition, subtraction, multiplication and division. Especially when mapping with database Decimal type fields, BigDecimal is the optimal
solution.
(2) Use an integer
to expand the value involved in the operation by 100 times, convert it to an integer, and then reduce it by 100 times when displaying it. The
advantage is that the calculation is simple and accurate. ) are used more. This method is also used in some
retail
POS machines, where the input and output are all integers, which makes the operation simpler .

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325849252&siteId=291194637