Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What is the use of BigDecimal in Java

2025-01-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/03 Report--

This article mainly introduces the use of BigDecimal in Java, has a certain reference value, interested friends can refer to, I hope you can learn a lot after reading this article, the following let the editor take you to understand it.

Why BigDecimal? what does he do?

The main design goals of the float and double types are for scientific and engineering calculations. They perform binary floating-point operations, which are carefully designed to provide more accurate and fast approximate calculations over a wide range of values. However, they do not provide completely accurate results, so they should not be used in situations where accurate results are required. However, business computing often requires accurate results, so it's time to use BigDecimal.

What is BigDecimal?

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

This article will give you a detailed introduction to the pits of BigDecimal accuracy and equality comparison in Java. Let's take a look at the detailed introduction.

Think about it for a moment, how do you usually create BigDecimal objects?

New one, pass in the value

BigDecimal.valueOf method, passing in the value

As a numeric type, it is common to compare size, and one case is to compare whether it is equal or not. Using equal method or compareTo method? This is a big pit.

/ / new pass a doubleBigDecimal newZero = new BigDecimal (0.0); System.out.println (BigDecimal.ZERO.equals (newZero)); / / new pass a string BigDecimal stringNewZero = new BigDecimal ("0.0"); System.out.println (BigDecimal.ZERO.equals (stringNewZero)); / / valueOf pass a doubleBigDecimal noScaleZero = BigDecimal.valueOf (0.0); System.out.println (BigDecimal.ZERO.equals (noScaleZero)) / / valueOf input a double, and then manually set the precision to 1BigDecimal scaleZero = BigDecimal.valueOf (0.0) .setScale (1); System.out.println (BigDecimal.ZERO.equals (scaleZero))

The values used for comparison are all 0. Guess what the above equals methods return? All true? No no no...

True

False

False

False

Are you surprised? are you surprised? What is the reason? Take a look at the implementation of BigDecimal's equals method:

Public boolean equals (Object x) {/ / type is different, directly return false if (! (x instanceof BigDecimal)) return false; BigDecimal xDec = (BigDecimal) x; / / the same object, directly return true if (x = = this) return true; / / with different precision, directly return false! If (scale! = xDec.scale) return false; long s = this.intCompact; long xs = xDec.intCompact; if (s! = INFLATED) {if (xs = = INFLATED) xs = compactValFor (xDec.intVal); return xs = = s;} else if (xs! = INFLATED) return xs = = compactValFor (this.intVal); return this.inflated (). Equals (xDec.inflated ());}

As can be seen from the first three simple judgments, debug will know that three of the above equals methods return false, all because of differences in precision. So what is the accuracy of BigDecimal.ZERO? Look at the source code:

/ Cache of common small BigDecimal values.private static final BigDecimal zeroThroughTen [] = {new BigDecimal (BigInteger.ZERO, 0,0,1), new BigDecimal (BigInteger.ONE, 1,0,1), new BigDecimal (BigInteger.valueOf (2), 2,0,1), new BigDecimal (BigInteger.valueOf (3), 3,0,1), new BigDecimal (BigInteger.valueOf (4), 4,0,1), new BigDecimal (BigInteger.valueOf (5), 5,0,1), new BigDecimal (BigInteger.valueOf (6), 6,0) 1), new BigDecimal (BigInteger.valueOf (7), 7,0,1), new BigDecimal (BigInteger.valueOf (8), 8,0,1), new BigDecimal (BigInteger.valueOf (9), 9,0,1), new BigDecimal (BigInteger.TEN, 10,0,2),} / * The value 0, with a scale of 0. * * @ since 1.5 * / public static final BigDecimal ZERO = zeroThroughTen [0]

The value of BigDecimal.Zero is 0 and the precision is 0.

The above case that returns false are all due to differences in precision. The reason for the difference in precision is that BigDecimal objects are initialized in different ways. From the source code point of view, the first three initialization methods are different.

Therefore, when the BigDecimal is relatively large, it is more reliable to use the compareTo method. After changing to compareTo, the results returned by the above four case are all equal:

BigDecimal newZero = new BigDecimal (0.0); System.out.println (BigDecimal.ZERO.compareTo (newZero)); BigDecimal stringNewZero = new BigDecimal ("0.0"); System.out.println (BigDecimal.ZERO.compareTo (stringNewZero)); BigDecimal noScaleZero = BigDecimal.valueOf (0.0); System.out.println (BigDecimal.ZERO.compareTo (noScaleZero)); BigDecimal scaleZero = BigDecimal.valueOf (0.0) .setScale (1); System.out.println (BigDecimal.ZERO.compareTo (scaleZero))

Output result

0

0

0

0

A bigger pit associated with this is that if you take the value of BigDecimal as the key of HashMap, because of the accuracy problem, the same value may have different hashCode values and the equals method returns false, resulting in put and get being likely to have the same value but accessing different value.

Think again, the decimal type can not be accurately stored in the computer, then it is quite unreliable to use it as the key of HashMap, and it will be used less in the future.

Another thing to note is that when writing code to call other people's methods, it's best to click in and take a look at the implementation. No matter how small the method is, there may be a big pit.

Thank you for reading this article carefully. I hope the article "what is the use of BigDecimal in Java" shared by the editor will be helpful to you. At the same time, I also hope you will support us and pay attention to the industry information channel. More related knowledge is waiting for you to learn!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report