decimal.md 4.3 KB
Newer Older
I
Ivan Blinkov 已提交
1 2 3 4 5
---
toc_priority: 42
toc_title: Decimal
---

6
# Decimal(P, S), Decimal32(S), Decimal64(S), Decimal128(S), Decimal256(S) {#decimalp-s-decimal32s-decimal64s-decimal128s}
I
Ivan Blinkov 已提交
7

8
Signed fixed-point numbers that keep precision during add, subtract and multiply operations. For division least significant digits are discarded (not rounded).
I
Ivan Blinkov 已提交
9

10
## Parameters {#parameters}
I
Ivan Blinkov 已提交
11

12
-   P - precision. Valid range: \[ 1 : 76 \]. Determines how many decimal digits number can have (including fraction).
13
-   S - scale. Valid range: \[ 0 : P \]. Determines how many decimal digits fraction can have.
I
Ivan Blinkov 已提交
14 15

Depending on P parameter value Decimal(P, S) is a synonym for:
16 17 18
- P from \[ 1 : 9 \] - for Decimal32(S)
- P from \[ 10 : 18 \] - for Decimal64(S)
- P from \[ 19 : 38 \] - for Decimal128(S)
19
- P from \[ 39 : 76 \] - for Decimal256(S)
I
Ivan Blinkov 已提交
20

21
## Decimal Value Ranges {#decimal-value-ranges}
I
Ivan Blinkov 已提交
22

23 24 25
-   Decimal32(S) - ( -1 \* 10^(9 - S), 1 \* 10^(9 - S) )
-   Decimal64(S) - ( -1 \* 10^(18 - S), 1 \* 10^(18 - S) )
-   Decimal128(S) - ( -1 \* 10^(38 - S), 1 \* 10^(38 - S) )
26
-   Decimal256(S) - ( -1 \* 10^(76 - S), 1 \* 10^(76 - S) )
I
Ivan Blinkov 已提交
27 28 29

For example, Decimal32(4) can contain numbers from -99999.9999 to 99999.9999 with 0.0001 step.

30
## Internal Representation {#internal-representation}
I
Ivan Blinkov 已提交
31

32
Internally data is represented as normal signed integers with respective bit width. Real value ranges that can be stored in memory are a bit larger than specified above, which are checked only on conversion from a string.
I
Ivan Blinkov 已提交
33

34
Because modern CPU’s do not support 128-bit integers natively, operations on Decimal128 are emulated. Because of this Decimal128 works significantly slower than Decimal32/Decimal64.
I
Ivan Blinkov 已提交
35

36
## Operations and Result Type {#operations-and-result-type}
I
Ivan Blinkov 已提交
37 38 39

Binary operations on Decimal result in wider result type (with any order of arguments).

40 41 42
-   `Decimal64(S1) <op> Decimal32(S2) -> Decimal64(S)`
-   `Decimal128(S1) <op> Decimal32(S2) -> Decimal128(S)`
-   `Decimal128(S1) <op> Decimal64(S2) -> Decimal128(S)`
43
-   `Decimal256(S1) <op> Decimal<32|64|128>(S2) -> Decimal256(S)`
I
Ivan Blinkov 已提交
44 45 46

Rules for scale:

47 48 49
-   add, subtract: S = max(S1, S2).
-   multuply: S = S1 + S2.
-   divide: S = S1.
I
Ivan Blinkov 已提交
50

51
For similar operations between Decimal and integers, the result is Decimal of the same size as an argument.
I
Ivan Blinkov 已提交
52

53
Operations between Decimal and Float32/Float64 are not defined. If you need them, you can explicitly cast one of argument using toDecimal32, toDecimal64, toDecimal128 or toFloat32, toFloat64 builtins. Keep in mind that the result will lose precision and type conversion is a computationally expensive operation.
I
Ivan Blinkov 已提交
54

55
Some functions on Decimal return result as Float64 (for example, var or stddev). Intermediate calculations might still be performed in Decimal, which might lead to different results between Float64 and Decimal inputs with the same values.
I
Ivan Blinkov 已提交
56

57
## Overflow Checks {#overflow-checks}
I
Ivan Blinkov 已提交
58

59
During calculations on Decimal, integer overflows might happen. Excessive digits in a fraction are discarded (not rounded). Excessive digits in integer part will lead to an exception.
I
Ivan Blinkov 已提交
60

61
``` sql
I
Ivan Blinkov 已提交
62 63
SELECT toDecimal32(2, 4) AS x, x / 3
```
64 65

``` text
I
Ivan Blinkov 已提交
66 67 68 69 70
┌──────x─┬─divide(toDecimal32(2, 4), 3)─┐
│ 2.0000 │                       0.6666 │
└────────┴──────────────────────────────┘
```

71
``` sql
I
Ivan Blinkov 已提交
72 73
SELECT toDecimal32(4.2, 8) AS x, x * x
```
74 75

``` text
I
Ivan Blinkov 已提交
76 77 78
DB::Exception: Scale is out of bounds.
```

79
``` sql
I
Ivan Blinkov 已提交
80 81
SELECT toDecimal32(4.2, 8) AS x, 6 * x
```
82 83

``` text
I
Ivan Blinkov 已提交
84 85 86 87 88
DB::Exception: Decimal math overflow.
```

Overflow checks lead to operations slowdown. If it is known that overflows are not possible, it makes sense to disable checks using `decimal_check_overflow` setting. When checks are disabled and overflow happens, the result will be incorrect:

89
``` sql
I
Ivan Blinkov 已提交
90 91 92
SET decimal_check_overflow = 0;
SELECT toDecimal32(4.2, 8) AS x, 6 * x
```
93 94

``` text
I
Ivan Blinkov 已提交
95 96 97 98 99
┌──────────x─┬─multiply(6, toDecimal32(4.2, 8))─┐
│ 4.20000000 │                     -17.74967296 │
└────────────┴──────────────────────────────────┘
```

100
Overflow checks happen not only on arithmetic operations but also on value comparison:
I
Ivan Blinkov 已提交
101

102
``` sql
I
Ivan Blinkov 已提交
103 104
SELECT toDecimal32(1, 8) < 100
```
105 106

``` text
I
Ivan Blinkov 已提交
107 108
DB::Exception: Can't compare.
```
I
Ivan Blinkov 已提交
109

I
Ivan Blinkov 已提交
110
[Original article](https://clickhouse.tech/docs/en/data_types/decimal/) <!--hide-->