110

I'm using BigDecimal for my numbers in my application, for example, with JPA. I did a bit of researching about the terms 'precision' and 'scale' but I don't understand what are they exactly.

Can anyone explain me the meaning of 'precision' and 'scale' for a BigDecimal value?

@Column(precision = 11, scale = 2)

Thanks!

jpadilladev
  • 1,756
  • 4
  • 16
  • 23
  • 2
    The question has got absolutely nothing to with `java.math.BigDecimal`. `@javax.persistence.Column` is not part of Java SE. It is the subject of JPA. – Tiny Feb 16 '16 at 15:49
  • 8
    Precision and scale are terms often used for java.math.BigDecimal, which is what he uses for calculations, for example with JPA. ISTM he or she wants to know what they mean in the context of BigDecimal alright. – Rudy Velthuis Feb 16 '16 at 22:40

6 Answers6

160

A BigDecimal is defined by two values: an arbitrary precision integer and a 32-bit integer scale. The value of the BigDecimal is defined to be unscaledValue*10^{-scale}.

Precision:

The precision is the number of digits in the unscaled value. For instance, for the number 123.45, the precision returned is 5.

So, precision indicates the length of the arbitrary precision integer. Here are a few examples of numbers with the same scale, but different precision:

  • 12345 / 100000 = 0.12345 // scale = 5, precision = 5
  • 12340 / 100000 = 0.1234 // scale = 4, precision = 4
  • 1 / 100000 = 0.00001 // scale = 5, precision = 1

In the special case that the number is equal to zero (i.e. 0.000), the precision is always 1.

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. For example, a scale of -3 means the unscaled value is multiplied by 1000.

This means that the integer value of the ‘BigDecimal’ is multiplied by 10^{-scale}.

Here are a few examples of the same precision, with different scales:

  • 12345 with scale 5 = 0.12345
  • 12345 with scale 4 = 1.2345
  • 12345 with scale 0 = 12345
  • 12345 with scale -1 = 123450

BigDecimal.toString:

The toString method for a BigDecimal behaves differently based on the scale and precision. (Thanks to @RudyVelthuis for pointing this out.)

  • If scale == 0, the integer is just printed out, as-is.
  • If scale < 0, E-Notation is always used (e.g. 5 scale -1 produces "5E+1")
  • If scale >= 0 and precision - scale -1 >= -6 a plain decimal number is produced (e.g. 10000000 scale 1 produces "1000000.0")
  • Otherwise, E-notation is used, e.g. 10 scale 8 produces "1.0E-7" since precision - scale -1 equals unscaledValue*10^{-scale} is less than -6.

More examples:

  • 19/100 = 0.19 // integer=19, scale=2, precision=2
  • 1/1000 = 0.0001 // integer=1, scale = 4, precision = 1
jumping_monkey
  • 5,941
  • 2
  • 43
  • 58
Austin
  • 8,018
  • 2
  • 31
  • 37
  • 3
    Actually, `[12345, -1]` is better represented by `1.2345E+5`, which is probably what `ToString` will return, too. Otherwise, very nice explanation. – Rudy Velthuis Feb 16 '16 at 22:43
  • @RudyVelthuis Thanks, I added a section explaining how the toString method determines whethe or not to use E+ notation – Austin Feb 17 '16 at 14:03
  • 1
    Heck, I see I wrote `ToString`. That is Delphi speak, not Java. ;-) – Rudy Velthuis Feb 18 '16 at 17:07
  • 1
    0.12345 - this is six digits total, not five – jarosik Mar 18 '19 at 13:56
  • @jarosik 0.12345 has scale of 5 because there are 5 digits to the right of the decimal point. That there are six digits displayed doesn't necessarily matter. – Austin Mar 23 '19 at 00:58
  • 3
    Your example and reference contradict each other: Reference reads as `If zero or positive, the scale is the number of digits to the right of the decimal point` but in your example, you wrote `0.12345 // scale = 5` and `0.1234 // scale = 5` – Farid Dec 25 '20 at 10:07
  • @Farid, `0.1234` is mathematically equivalent to `0.12340`. – gagarwa May 10 '21 at 07:44
  • 1
    why the scale is not 4 below? 12340 / 100000 = 0.1234 // scale = 5, precision = 4 – Koushik Roy Aug 27 '21 at 13:25
  • When I do `println(BigDecimal(12345).setScale(2))` then result is 12345.00 and not 0.12345 as mentioned in the answer – firstpostcommenter Oct 19 '22 at 08:13
  • @firstpostcommenter I'm not sure where the answer mentions 12345.00 versus 0.12345, but I suggest you check the JavaDocs on what *exactly* `setScale()` is doing: It returns a BigDecimal whose scale is the specified value, and whose value is numerically equal to this BigDecimal's. So, if `bd` is a BigDecimal, then `bd.equals(bd.setScale(2))` is `true`. – Austin Oct 20 '22 at 13:54
85
  • Precision: Total number of significant digits

  • Scale: Number of digits to the right of the decimal point

See BigDecimal class documentation for details.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
hamena314
  • 2,969
  • 5
  • 30
  • 57
4

Quoting Javadoc:

The precision is the number of digits in the unscaled value.

and

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. For example, a scale of -3 means the unscaled value is multiplied by 1000.

Andy Turner
  • 137,514
  • 11
  • 162
  • 243
4

Precision is the total number of significant digits in a number. Scale is the number of digits to the right of the decimal point.

Examples:

123.456 Precision=6 Scale=3

10 Precision=2 Scale=0

-96.9923 Precision=6 Scale=4

0.0 Precision=1 Scale=1

Negative Scale

For a negative scale value, we apply the following formula: result = (given number) * 10 ^ (-(scale value)) Example

Given number = 1234.56

scale = -5

-> (1234.56) * 10^(-(-5))

-> (1234.56) * 10^(+5)

-> 123456000

Reference: https://www.logicbig.com/quick-info/programming/precision-and-scale.html

Shadyar
  • 709
  • 8
  • 16
3

From your example annotation the maximum digits is 2 after the decimal point and 9 before (totally 11): 123456789,01

adranale
  • 2,835
  • 1
  • 21
  • 39
0

The JPA annotation @Column(precision = 11, scale = 2) for BigDecimal variable translates to DECIMAL(11,2) in the MYSQL database.

This means, the column can store a value having 11 digits in total, with 2 digits allowed after the decimal. ie. the Range here would be [-999999999.99,999999999.99]

imAmanRana
  • 123
  • 1
  • 3
  • 9