Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

data type to represent a big decimal in java

Which data type is apt to represent a decimal number like "10364055.81".

If tried using double:

double d = 10364055.81;

But when I try to print the number, its displaying as "1.036405581E7", which I don't want.

Should I use BigDecimal? But its displaying as 10364055.81000000052154064178466796875. Is there any datatype that displays the values as it is? Also the number may be bigger than the one taken as example.

BTW, will using BigDecimal effect the performance of the application?? I might use this in almost all my DTOs.

like image 327
jai Avatar asked Oct 22 '09 09:10

jai


People also ask

What is a big decimal in Java?

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 to the right of the decimal point. If negative, the unscaled value of the number is multiplied by ten to the power of the negation of the scale.

How do you assign a value to big decimal?

BigDecimal. valueOf(long val) translates a long value into a BigDecimal with a scale of zero. This "static factory method" is provided in preference to a (long) constructor because it allows for reuse of frequently used BigDecimal values.

Is BigDecimal primitive in Java?

These basic arithmetic operations can be performed on BigDecimal, and between BigDecimal and primitive data types. This is what we will cover in this article. While both BigInteger and BigDecimal support arbitrary-precision integers, BigDecimal only supports arbitrary-precision, fixed-point numbers.


1 Answers

You should use BigDecimal - but use the String constructor, e.g.:

new BigDecimal("10364055.81");

If you pass a double to BigDecimal, Java must create that double first - and since doubles cannot represent most decimal fractions accurately, it does create the value as 10364055.81000000052154064178466796875 and then passes it to the BigDecimal constructor. In this case BigDecimal has no way of knowing that you actually meant the rounder version.

Generally speaking, using non-String constructors of BigDecimal should be considered a warning that you're not getting the full benefit of the class.

Edit - based on rereading exactly what you wanted to do, my initial claim is probably too strong. BigDecimal is a good choice when you need to represent decimal values exactly (money handling being the obvious choice, you don't want 5.99 * one million to be 5990016.45 for example.

But if you're not worried about the number being stored internally as a very slightly different value to the decimal literal you entered, and just want to print it out again in the same format, then as others have said, an instance of NumberFormat (in this case, new DecimalFormat("########.##")) will do the trick to output the double nicely, or String.format can do much the same thing.

As for performance - BigDecimals will naturally be slower than using primitives. Typically, though, unless the vast majority of your program involves mathematical manipulations, you're unlikely to actually notice any speed difference. That's not to say you should use BigDecimals all over; but rather, that if you can get a real benefit from their features that would be difficult or impossible to realise with plain doubles, then don't sweat the miniscule performance difference they theoretically introduce.

like image 98
Andrzej Doyle Avatar answered Sep 21 '22 01:09

Andrzej Doyle