mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-10-22 08:20:48 +00:00
2d2bc052e1
* Typo fix. * Links fix. * Fixed links in docs. * More fixes. * docs/en: cleaning some files * docs/en: cleaning data_types * docs/en: cleaning database_engines * docs/en: cleaning development * docs/en: cleaning getting_started * docs/en: cleaning interfaces * docs/en: cleaning operations * docs/en: cleaning query_lamguage * docs/en: cleaning en * docs/ru: cleaning data_types * docs/ru: cleaning index * docs/ru: cleaning database_engines * docs/ru: cleaning development * docs/ru: cleaning general * docs/ru: cleaning getting_started * docs/ru: cleaning interfaces * docs/ru: cleaning operations * docs/ru: cleaning query_language * docs: cleaning interfaces/http * Update docs/en/data_types/array.md decorated ``` Co-Authored-By: BayoNet <da-daos@yandex.ru> * Update docs/en/getting_started/example_datasets/nyc_taxi.md fixed typo Co-Authored-By: BayoNet <da-daos@yandex.ru> * Update docs/en/getting_started/example_datasets/ontime.md fixed typo Co-Authored-By: BayoNet <da-daos@yandex.ru> * Update docs/en/interfaces/formats.md fixed error Co-Authored-By: BayoNet <da-daos@yandex.ru> * Update docs/en/operations/table_engines/custom_partitioning_key.md Co-Authored-By: BayoNet <da-daos@yandex.ru> * Update docs/en/operations/utils/clickhouse-local.md Co-Authored-By: BayoNet <da-daos@yandex.ru> * Update docs/en/query_language/dicts/external_dicts_dict_sources.md Co-Authored-By: BayoNet <da-daos@yandex.ru> * Update docs/en/operations/utils/clickhouse-local.md Co-Authored-By: BayoNet <da-daos@yandex.ru> * Update docs/en/query_language/functions/json_functions.md Co-Authored-By: BayoNet <da-daos@yandex.ru> * Update docs/en/query_language/functions/json_functions.md Co-Authored-By: BayoNet <da-daos@yandex.ru> * Update docs/en/query_language/functions/other_functions.md Co-Authored-By: BayoNet <da-daos@yandex.ru> * Update docs/en/query_language/functions/other_functions.md Co-Authored-By: BayoNet <da-daos@yandex.ru> * Update docs/en/query_language/functions/date_time_functions.md Co-Authored-By: BayoNet <da-daos@yandex.ru> * Update docs/en/operations/table_engines/jdbc.md Co-Authored-By: BayoNet <da-daos@yandex.ru> * docs: fixed error * docs: fixed error
97 lines
6.2 KiB
Markdown
97 lines
6.2 KiB
Markdown
|
||
# Decimal(P, S), Decimal32(S), Decimal64(S), Decimal128(S)
|
||
|
||
Знаковые дробные числа с сохранением точности операций сложения, умножения и вычитания. Для деления осуществляется отбрасывание (не округление) знаков, не попадающих в младший десятичный разряд.
|
||
|
||
## Параметры
|
||
|
||
- P - precision. Значение из диапазона [ 1 : 38 ]. Определяет, сколько десятичных знаков (с учетом дробной части) может содержать число.
|
||
- S - scale. Значение из диапазона [ 0 : P ]. Определяет, сколько десятичных знаков содержится в дробной части числа.
|
||
|
||
В зависимости от параметра P Decimal(P, S) является синонимом:
|
||
- P из [ 1 : 9 ] - для Decimal32(S)
|
||
- P из [ 10 : 18 ] - для Decimal64(S)
|
||
- P из [ 19 : 38 ] - для Decimal128(S)
|
||
|
||
## Диапазоны Decimal
|
||
|
||
- 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) )
|
||
|
||
Например, Decimal32(4) содержит числа от -99999.9999 до 99999.9999 c шагом 0.0001.
|
||
|
||
## Внутреннее представление
|
||
|
||
Внутри данные представляются как знаковые целые числа, соответсвующей разрядности. Реальные диапазоны, хранящиеся в ячейках памяти несколько больше заявленных. Заявленные диапазоны Decimal проверяются только при вводе числа из строкового представления.
|
||
Поскольку современные CPU не поддерживают 128-битные числа, операции над Decimal128 эмулируются программно. Decimal128 работает в разы медленней чем Decimal32/Decimal64.
|
||
|
||
## Операции и типы результата
|
||
|
||
Результат операции между двумя Decimal расширяется до большего типа (независимо от порядка аргументов).
|
||
|
||
- Decimal64(S1) <op> Decimal32(S2) -> Decimal64(S)
|
||
- Decimal128(S1) <op> Decimal32(S2) -> Decimal128(S)
|
||
- Decimal128(S1) <op> Decimal64(S2) -> Decimal128(S)
|
||
|
||
Для размера дробной части (scale) результата действуют следующие правила:
|
||
|
||
- сложение, вычитание: S = max(S1, S2).
|
||
- умножение: S = S1 + S2.
|
||
- деление: S = S1.
|
||
|
||
При операциях между Decimal и целыми числами результатом является Decimal, аналогичный аргументу.
|
||
|
||
Операции между Decimal и Float32/64 не определены. Для осуществления таких операций нужно явно привести один из агруметнов функциями: toDecimal32, toDecimal64, toDecimal128, или toFloat32, toFloat64. Это сделано из двух соображений. Во-первых, результат операции будет с потерей точности. Во-вторых, преобразование типа - дорогая операция, из-за ее наличия пользовательский запрос может работать в несколько раз дольше.
|
||
|
||
Часть функций над Decimal возвращают Float64 (например, var, stddev). Для некоторых из них промежуточные операции проходят в Decimal.
|
||
Для таких функций результат над одинаковыми данными во Float64 и Decimal может отличаться, несмотря на одинаковый тип результата.
|
||
|
||
## Проверка переполнений
|
||
|
||
При выполнении операций над типом Decimal могут происходить целочисленные переполнения. Лишняя дробная часть отбрасывается (не округляется). Лишняя целочисленная часть приводит к исключению.
|
||
```sql
|
||
SELECT toDecimal32(2, 4) AS x, x / 3
|
||
```
|
||
```text
|
||
┌──────x─┬─divide(toDecimal32(2, 4), 3)─┐
|
||
│ 2.0000 │ 0.6666 │
|
||
└────────┴──────────────────────────────┘
|
||
```
|
||
|
||
```sql
|
||
SELECT toDecimal32(4.2, 8) AS x, x * x
|
||
```
|
||
```text
|
||
DB::Exception: Scale is out of bounds.
|
||
```
|
||
|
||
```sql
|
||
SELECT toDecimal32(4.2, 8) AS x, 6 * x
|
||
```
|
||
```text
|
||
DB::Exception: Decimal math overflow.
|
||
```
|
||
|
||
Проверка переполнения приводит к замедлению операций. При уверенности, что типа результата хватит для его записи проверку переполнения можно отключить настройкой decimal_check_overflow. В этом случае при переполнении вернется неверное значение:
|
||
```sql
|
||
SET decimal_check_overflow = 0;
|
||
SELECT toDecimal32(4.2, 8) AS x, 6 * x
|
||
```
|
||
```text
|
||
┌──────────x─┬─multiply(6, toDecimal32(4.2, 8))─┐
|
||
│ 4.20000000 │ -17.74967296 │
|
||
└────────────┴──────────────────────────────────┘
|
||
```
|
||
|
||
Переполнения происходят не только на арифметических операциях, но и на операциях сравнения. Отключать проверку стоит только при полной уверенности в корректности результата:
|
||
|
||
```sql
|
||
SELECT toDecimal32(1, 8) < 100
|
||
```
|
||
```text
|
||
DB::Exception: Can't compare.
|
||
```
|
||
|
||
[Оригинальная статья](https://clickhouse.yandex/docs/ru/data_types/decimal/) <!--hide-->
|