---
title: Decimal Data Type reference
meta:
    description: Documentation for the Decimal data type.
---

# Decimal

Decimal data types represent signed fixed-point numbers, ensuring precise arithmetic for addition, subtraction, and multiplication. When performing division, any least significant digits are truncated rather than rounded.

This category includes `Decimal`, `Decimal(P)`, `Decimal(P, S)`, `Decimal32(S)`, `Decimal64(S)`, `Decimal128(S)`, and `Decimal256(S)`.

## Parameters

-   `P` (Precision): Defines the total number of decimal digits a number can hold, including both the integer and fractional parts. Its valid range is \[1 : 76\]. If not specified, the default precision is 10.
-   `S` (Scale): Specifies the number of digits allowed in the fractional part of the number. Its valid range is \[0 : P\].

The syntax `Decimal(P)` is equivalent to `Decimal(P, 0)`, meaning no fractional digits. Similarly, `Decimal` without any parameters defaults to `Decimal(10, 0)`.

Based on the precision `P`, `Decimal(P, S)` is an alias for:
-   `Decimal32(S)` for `P` values from \[1 : 9\]
-   `Decimal64(S)` for `P` values from \[10 : 18\]
-   `Decimal128(S)` for `P` values from \[19 : 38\]
-   `Decimal256(S)` for `P` values from \[39 : 76\]

## Decimal value ranges

The range of values a Decimal type can store depends on its precision and scale:

-   `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) )
-   `Decimal256(S)`: ( -1 \* 10^(76 - S), 1 \* 10^(76 - S) )

For example, a `Decimal32(4)` type can store numbers ranging from -99999.9999 to 99999.9999, with a minimum step of 0.0001.

## Internal representation

Internally, Decimal values are stored as standard signed integers with varying bit widths. While the actual memory capacity might be slightly larger, the specified ranges are enforced during string conversions.

Operations on `Decimal128` and `Decimal256` are emulated because modern CPUs do not natively support 128-bit and 256-bit integers. This emulation means that `Decimal128` and `Decimal256` types perform significantly slower than `Decimal32` or `Decimal64`.

## Operations and result type

Binary operations involving Decimal types typically result in a wider Decimal type to maintain precision. The order of arguments does not affect this.

-   `Decimal64(S1) <operator> Decimal32(S2)` results in `Decimal64(S)`
-   `Decimal128(S1) <operator> Decimal32(S2)` results in `Decimal128(S)`
-   `Decimal128(S1) <operator> Decimal64(S2)` results in `Decimal128(S)`
-   `Decimal256(S1) <operator> Decimal<32|64|128>(S2)` results in `Decimal256(S)`

Rules for determining the scale (`S`) of the result:

-   For addition and subtraction: `S = max(S1, S2)`.
-   For multiplication: `S = S1 + S2`.
-   For division: `S = S1`.

When performing operations between a Decimal type and an integer, the result will be a Decimal type of the same size as the original Decimal argument.

Direct operations between Decimal types and `Float32` or `Float64` are not supported. To perform such operations, you must explicitly cast one of the arguments using functions like `toDecimal32`, `toDecimal64`, `toDecimal128`, `toFloat32`, or `toFloat64`. Be aware that type conversions can lead to a loss of precision and are computationally intensive.

Some functions, such as `var` or `stddev`, may return results as `Float64` even when operating on Decimal inputs. Intermediate calculations might still use Decimal precision, which could lead to different results compared to direct `Float64` inputs with the same values.

## Overflow checks

During calculations with Decimal types, integer overflows can occur. If the fractional part of a number exceeds its defined scale, the excess digits are truncated (not rounded). However, if the integer part overflows its capacity, an exception will be thrown.

{% callout type="caution" %}
Overflow checking is not implemented for `Decimal128` and `Decimal256`. In the event of an overflow with these types, an incorrect result will be returned without an exception being thrown.
{% /callout %}

```sql
SELECT toDecimal32(2, 4) AS x, x / 3
```

Result:

```result
┌──────x─┬─divide(toDecimal32(2, 4), 3)─┐
│ 2.0000 │                       0.6666 │
└────────┴──────────────────────────────┘
```

```sql
SELECT toDecimal32(4.2, 8) AS x, x * x
```

Result:

```text
DB::Exception: Scale is out of bounds.
```

```sql
SELECT toDecimal32(4.2, 8) AS x, 6 * x
```

Result:

```text
DB::Exception: Decimal math overflow.
```

Overflow checks can impact performance. If you are certain that overflows will not occur in your calculations, you can disable these checks using the `decimal_check_overflow` setting. If checks are disabled and an overflow happens, the result will be incorrect.

Overflow checks are also performed during value comparisons:

```sql
SELECT toDecimal32(1, 8) < 100
```

Result:

```text
DB::Exception: Can't compare.
```
