Skip to main content

arrow_data/
decimal.rs

1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: See the NOTICE file distributed with this work for additional information regarding copyright ownership
3// SPDX-FileContributor: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements
4
5//! Maximum and minimum values for [`Decimal256`], [`Decimal128`], [`Decimal64`] and [`Decimal32`].
6//!
7//! Also provides functions to validate if a given decimal value is within
8//! the valid range of the decimal type.
9//!
10//! [`Decimal32`]: arrow_schema::DataType::Decimal32
11//! [`Decimal64`]: arrow_schema::DataType::Decimal64
12//! [`Decimal128`]: arrow_schema::DataType::Decimal128
13//! [`Decimal256`]: arrow_schema::DataType::Decimal256
14use arrow_buffer::i256;
15use arrow_schema::ArrowError;
16use std::fmt::{Display, Write};
17
18pub use arrow_schema::{
19    DECIMAL_DEFAULT_SCALE, DECIMAL32_DEFAULT_SCALE, DECIMAL32_MAX_PRECISION, DECIMAL32_MAX_SCALE,
20    DECIMAL64_DEFAULT_SCALE, DECIMAL64_MAX_PRECISION, DECIMAL64_MAX_SCALE,
21    DECIMAL128_MAX_PRECISION, DECIMAL128_MAX_SCALE, DECIMAL256_MAX_PRECISION, DECIMAL256_MAX_SCALE,
22};
23
24/// `MAX_DECIMAL256_FOR_EACH_PRECISION[p]` holds the maximum [`i256`] value that can
25/// be stored in a [`Decimal256`] value of precision `p`.
26///
27/// # Notes
28///
29/// Each element is the max value of signed 256-bit integer for the specified
30/// precision which is encoded to the 32-byte width format of little-endian.
31///
32/// The first element is unused and is inserted so that we can look up using
33/// precision as the index without the need to subtract 1 first.
34///
35/// # Example
36/// ```
37/// # use arrow_buffer::i256;
38/// # use arrow_data::decimal::MAX_DECIMAL256_FOR_EACH_PRECISION;
39/// assert_eq!(MAX_DECIMAL256_FOR_EACH_PRECISION[3], i256::from(999));
40/// ```
41///
42/// [`Decimal256`]: arrow_schema::DataType::Decimal256
43/// [`i256`]: arrow_buffer::i256
44pub const MAX_DECIMAL256_FOR_EACH_PRECISION: [i256; 77] = [
45    i256::from_i128(0_i128), // unused first element
46    i256::from_le_bytes([
47        9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
48        0, 0,
49    ]),
50    i256::from_le_bytes([
51        99, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
52        0, 0,
53    ]),
54    i256::from_le_bytes([
55        231, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
56        0, 0,
57    ]),
58    i256::from_le_bytes([
59        15, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
60        0, 0,
61    ]),
62    i256::from_le_bytes([
63        159, 134, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
64        0, 0, 0,
65    ]),
66    i256::from_le_bytes([
67        63, 66, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
68        0, 0, 0,
69    ]),
70    i256::from_le_bytes([
71        127, 150, 152, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
72        0, 0, 0, 0,
73    ]),
74    i256::from_le_bytes([
75        255, 224, 245, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
76        0, 0, 0, 0,
77    ]),
78    i256::from_le_bytes([
79        255, 201, 154, 59, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
80        0, 0, 0, 0,
81    ]),
82    i256::from_le_bytes([
83        255, 227, 11, 84, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
84        0, 0, 0, 0,
85    ]),
86    i256::from_le_bytes([
87        255, 231, 118, 72, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
88        0, 0, 0, 0,
89    ]),
90    i256::from_le_bytes([
91        255, 15, 165, 212, 232, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
92        0, 0, 0, 0, 0,
93    ]),
94    i256::from_le_bytes([
95        255, 159, 114, 78, 24, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
96        0, 0, 0, 0,
97    ]),
98    i256::from_le_bytes([
99        255, 63, 122, 16, 243, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
100        0, 0, 0, 0, 0,
101    ]),
102    i256::from_le_bytes([
103        255, 127, 198, 164, 126, 141, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
104        0, 0, 0, 0, 0, 0,
105    ]),
106    i256::from_le_bytes([
107        255, 255, 192, 111, 242, 134, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
108        0, 0, 0, 0, 0, 0,
109    ]),
110    i256::from_le_bytes([
111        255, 255, 137, 93, 120, 69, 99, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
112        0, 0, 0, 0, 0,
113    ]),
114    i256::from_le_bytes([
115        255, 255, 99, 167, 179, 182, 224, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
116        0, 0, 0, 0, 0, 0,
117    ]),
118    i256::from_le_bytes([
119        255, 255, 231, 137, 4, 35, 199, 138, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
120        0, 0, 0, 0, 0, 0,
121    ]),
122    i256::from_le_bytes([
123        255, 255, 15, 99, 45, 94, 199, 107, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
124        0, 0, 0, 0, 0, 0,
125    ]),
126    i256::from_le_bytes([
127        255, 255, 159, 222, 197, 173, 201, 53, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
128        0, 0, 0, 0, 0, 0, 0,
129    ]),
130    i256::from_le_bytes([
131        255, 255, 63, 178, 186, 201, 224, 25, 30, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
132        0, 0, 0, 0, 0, 0, 0,
133    ]),
134    i256::from_le_bytes([
135        255, 255, 127, 246, 74, 225, 199, 2, 45, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
136        0, 0, 0, 0, 0, 0, 0,
137    ]),
138    i256::from_le_bytes([
139        255, 255, 255, 160, 237, 204, 206, 27, 194, 211, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
140        0, 0, 0, 0, 0, 0, 0, 0,
141    ]),
142    i256::from_le_bytes([
143        255, 255, 255, 73, 72, 1, 20, 22, 149, 69, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
144        0, 0, 0, 0, 0, 0,
145    ]),
146    i256::from_le_bytes([
147        255, 255, 255, 227, 210, 12, 200, 220, 210, 183, 82, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
148        0, 0, 0, 0, 0, 0, 0, 0,
149    ]),
150    i256::from_le_bytes([
151        255, 255, 255, 231, 60, 128, 208, 159, 60, 46, 59, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
152        0, 0, 0, 0, 0, 0, 0, 0,
153    ]),
154    i256::from_le_bytes([
155        255, 255, 255, 15, 97, 2, 37, 62, 94, 206, 79, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
156        0, 0, 0, 0, 0, 0, 0,
157    ]),
158    i256::from_le_bytes([
159        255, 255, 255, 159, 202, 23, 114, 109, 174, 15, 30, 67, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
160        0, 0, 0, 0, 0, 0, 0, 0,
161    ]),
162    i256::from_le_bytes([
163        255, 255, 255, 63, 234, 237, 116, 70, 208, 156, 44, 159, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
164        0, 0, 0, 0, 0, 0, 0, 0, 0,
165    ]),
166    i256::from_le_bytes([
167        255, 255, 255, 127, 38, 75, 145, 192, 34, 32, 190, 55, 126, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
168        0, 0, 0, 0, 0, 0, 0, 0, 0,
169    ]),
170    i256::from_le_bytes([
171        255, 255, 255, 255, 128, 239, 172, 133, 91, 65, 109, 45, 238, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0,
172        0, 0, 0, 0, 0, 0, 0, 0, 0,
173    ]),
174    i256::from_le_bytes([
175        255, 255, 255, 255, 9, 91, 193, 56, 147, 141, 68, 198, 77, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0,
176        0, 0, 0, 0, 0, 0, 0, 0, 0,
177    ]),
178    i256::from_le_bytes([
179        255, 255, 255, 255, 99, 142, 141, 55, 192, 135, 173, 190, 9, 237, 1, 0, 0, 0, 0, 0, 0, 0,
180        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
181    ]),
182    i256::from_le_bytes([
183        255, 255, 255, 255, 231, 143, 135, 43, 130, 77, 199, 114, 97, 66, 19, 0, 0, 0, 0, 0, 0, 0,
184        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
185    ]),
186    i256::from_le_bytes([
187        255, 255, 255, 255, 15, 159, 75, 179, 21, 7, 201, 123, 206, 151, 192, 0, 0, 0, 0, 0, 0, 0,
188        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
189    ]),
190    i256::from_le_bytes([
191        255, 255, 255, 255, 159, 54, 244, 0, 217, 70, 218, 213, 16, 238, 133, 7, 0, 0, 0, 0, 0, 0,
192        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
193    ]),
194    i256::from_le_bytes([
195        255, 255, 255, 255, 63, 34, 138, 9, 122, 196, 134, 90, 168, 76, 59, 75, 0, 0, 0, 0, 0, 0,
196        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
197    ]),
198    i256::from_le_bytes([
199        255, 255, 255, 255, 127, 86, 101, 95, 196, 172, 67, 137, 147, 254, 80, 240, 2, 0, 0, 0, 0,
200        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
201    ]),
202    i256::from_le_bytes([
203        255, 255, 255, 255, 255, 96, 245, 185, 171, 191, 164, 92, 195, 241, 41, 99, 29, 0, 0, 0, 0,
204        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
205    ]),
206    i256::from_le_bytes([
207        255, 255, 255, 255, 255, 201, 149, 67, 181, 124, 111, 158, 161, 113, 163, 223, 37, 1, 0, 0,
208        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
209    ]),
210    i256::from_le_bytes([
211        255, 255, 255, 255, 255, 227, 217, 163, 20, 223, 90, 48, 80, 112, 98, 188, 122, 11, 0, 0,
212        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
213    ]),
214    i256::from_le_bytes([
215        255, 255, 255, 255, 255, 231, 130, 102, 206, 182, 140, 227, 33, 99, 216, 91, 203, 114, 0,
216        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
217    ]),
218    i256::from_le_bytes([
219        255, 255, 255, 255, 255, 15, 29, 1, 16, 36, 127, 227, 82, 223, 115, 150, 241, 123, 4, 0, 0,
220        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
221    ]),
222    i256::from_le_bytes([
223        255, 255, 255, 255, 255, 159, 34, 11, 160, 104, 247, 226, 60, 185, 134, 224, 111, 215, 44,
224        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
225    ]),
226    i256::from_le_bytes([
227        255, 255, 255, 255, 255, 63, 90, 111, 64, 22, 170, 221, 96, 60, 67, 197, 94, 106, 192, 1,
228        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
229    ]),
230    i256::from_le_bytes([
231        255, 255, 255, 255, 255, 127, 134, 89, 132, 222, 164, 168, 200, 91, 160, 180, 179, 39, 132,
232        17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
233    ]),
234    i256::from_le_bytes([
235        255, 255, 255, 255, 255, 255, 64, 127, 43, 177, 112, 150, 214, 149, 67, 14, 5, 141, 41,
236        175, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
237    ]),
238    i256::from_le_bytes([
239        255, 255, 255, 255, 255, 255, 137, 248, 178, 235, 102, 224, 97, 218, 163, 142, 50, 130,
240        159, 215, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
241    ]),
242    i256::from_le_bytes([
243        255, 255, 255, 255, 255, 255, 99, 181, 253, 52, 5, 196, 210, 135, 102, 146, 249, 21, 59,
244        108, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
245    ]),
246    i256::from_le_bytes([
247        255, 255, 255, 255, 255, 255, 231, 21, 233, 17, 52, 168, 59, 78, 1, 184, 191, 219, 78, 58,
248        172, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
249    ]),
250    i256::from_le_bytes([
251        255, 255, 255, 255, 255, 255, 15, 219, 26, 179, 8, 146, 84, 14, 13, 48, 125, 149, 20, 71,
252        186, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
253    ]),
254    i256::from_le_bytes([
255        255, 255, 255, 255, 255, 255, 159, 142, 12, 255, 86, 180, 77, 143, 130, 224, 227, 214, 205,
256        198, 70, 11, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
257    ]),
258    i256::from_le_bytes([
259        255, 255, 255, 255, 255, 255, 63, 146, 125, 246, 101, 11, 9, 153, 25, 197, 230, 100, 10,
260        196, 195, 112, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0,
261    ]),
262    i256::from_le_bytes([
263        255, 255, 255, 255, 255, 255, 127, 182, 231, 160, 251, 113, 90, 250, 255, 178, 3, 241, 103,
264        168, 165, 103, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0,
265    ]),
266    i256::from_le_bytes([
267        255, 255, 255, 255, 255, 255, 255, 32, 13, 73, 212, 115, 136, 199, 255, 253, 36, 106, 15,
268        148, 120, 12, 20, 4, 0, 0, 0, 0, 0, 0, 0, 0,
269    ]),
270    i256::from_le_bytes([
271        255, 255, 255, 255, 255, 255, 255, 73, 131, 218, 74, 134, 84, 203, 253, 235, 113, 37, 154,
272        200, 181, 124, 200, 40, 0, 0, 0, 0, 0, 0, 0, 0,
273    ]),
274    i256::from_le_bytes([
275        255, 255, 255, 255, 255, 255, 255, 227, 32, 137, 236, 62, 77, 241, 233, 55, 115, 118, 5,
276        214, 25, 223, 212, 151, 1, 0, 0, 0, 0, 0, 0, 0,
277    ]),
278    i256::from_le_bytes([
279        255, 255, 255, 255, 255, 255, 255, 231, 72, 91, 61, 117, 4, 109, 35, 47, 128, 160, 54, 92,
280        2, 183, 80, 238, 15, 0, 0, 0, 0, 0, 0, 0,
281    ]),
282    i256::from_le_bytes([
283        255, 255, 255, 255, 255, 255, 255, 15, 217, 144, 101, 148, 44, 66, 98, 215, 1, 69, 34, 154,
284        23, 38, 39, 79, 159, 0, 0, 0, 0, 0, 0, 0,
285    ]),
286    i256::from_le_bytes([
287        255, 255, 255, 255, 255, 255, 255, 159, 122, 168, 247, 203, 189, 149, 214, 105, 18, 178,
288        86, 5, 236, 124, 135, 23, 57, 6, 0, 0, 0, 0, 0, 0,
289    ]),
290    i256::from_le_bytes([
291        255, 255, 255, 255, 255, 255, 255, 63, 202, 148, 172, 247, 105, 217, 97, 34, 184, 244, 98,
292        53, 56, 225, 74, 235, 58, 62, 0, 0, 0, 0, 0, 0,
293    ]),
294    i256::from_le_bytes([
295        255, 255, 255, 255, 255, 255, 255, 127, 230, 207, 189, 172, 35, 126, 210, 87, 49, 143, 221,
296        21, 50, 204, 236, 48, 77, 110, 2, 0, 0, 0, 0, 0,
297    ]),
298    i256::from_le_bytes([
299        255, 255, 255, 255, 255, 255, 255, 255, 0, 31, 106, 191, 100, 237, 56, 110, 237, 151, 167,
300        218, 244, 249, 63, 233, 3, 79, 24, 0, 0, 0, 0, 0,
301    ]),
302    i256::from_le_bytes([
303        255, 255, 255, 255, 255, 255, 255, 255, 9, 54, 37, 122, 239, 69, 57, 78, 70, 239, 139, 138,
304        144, 195, 127, 28, 39, 22, 243, 0, 0, 0, 0, 0,
305    ]),
306    i256::from_le_bytes([
307        255, 255, 255, 255, 255, 255, 255, 255, 99, 28, 116, 197, 90, 187, 60, 14, 191, 88, 119,
308        105, 165, 163, 253, 28, 135, 221, 126, 9, 0, 0, 0, 0,
309    ]),
310    i256::from_le_bytes([
311        255, 255, 255, 255, 255, 255, 255, 255, 231, 27, 137, 182, 139, 81, 95, 142, 118, 119, 169,
312        30, 118, 100, 232, 33, 71, 167, 244, 94, 0, 0, 0, 0,
313    ]),
314    i256::from_le_bytes([
315        255, 255, 255, 255, 255, 255, 255, 255, 15, 23, 91, 33, 117, 47, 185, 143, 161, 170, 158,
316        50, 157, 236, 19, 83, 199, 136, 142, 181, 3, 0, 0, 0,
317    ]),
318    i256::from_le_bytes([
319        255, 255, 255, 255, 255, 255, 255, 255, 159, 230, 142, 77, 147, 218, 59, 157, 79, 170, 50,
320        250, 35, 62, 199, 62, 201, 87, 145, 23, 37, 0, 0, 0,
321    ]),
322    i256::from_le_bytes([
323        255, 255, 255, 255, 255, 255, 255, 255, 63, 2, 149, 7, 193, 137, 86, 36, 28, 167, 250, 197,
324        103, 109, 200, 115, 220, 109, 173, 235, 114, 1, 0, 0,
325    ]),
326    i256::from_le_bytes([
327        255, 255, 255, 255, 255, 255, 255, 255, 127, 22, 210, 75, 138, 97, 97, 107, 25, 135, 202,
328        187, 13, 70, 212, 133, 156, 74, 198, 52, 125, 14, 0, 0,
329    ]),
330    i256::from_le_bytes([
331        255, 255, 255, 255, 255, 255, 255, 255, 255, 224, 52, 246, 102, 207, 205, 49, 254, 70, 233,
332        85, 137, 188, 74, 58, 29, 234, 190, 15, 228, 144, 0, 0,
333    ]),
334    i256::from_le_bytes([
335        255, 255, 255, 255, 255, 255, 255, 255, 255, 201, 16, 158, 5, 26, 10, 242, 237, 197, 28,
336        91, 93, 93, 235, 70, 36, 37, 117, 157, 232, 168, 5, 0,
337    ]),
338    i256::from_le_bytes([
339        255, 255, 255, 255, 255, 255, 255, 255, 255, 227, 167, 44, 56, 4, 101, 116, 75, 187, 31,
340        143, 165, 165, 49, 197, 106, 115, 147, 38, 22, 153, 56, 0,
341    ]),
342    i256::from_le_bytes([
343        255, 255, 255, 255, 255, 255, 255, 255, 255, 231, 142, 190, 49, 42, 242, 139, 242, 80, 61,
344        151, 119, 120, 240, 179, 43, 130, 194, 129, 221, 250, 53, 2,
345    ]),
346    i256::from_le_bytes([
347        255, 255, 255, 255, 255, 255, 255, 255, 255, 15, 149, 113, 241, 165, 117, 119, 121, 41,
348        101, 232, 171, 180, 100, 7, 181, 21, 153, 17, 167, 204, 27, 22,
349    ]),
350];
351
352/// `MIN_DECIMAL256_FOR_EACH_PRECISION[p]` holds the minimum [`i256`] value that can
353/// be stored in a [`Decimal256`] value of precision `p`.
354///
355/// # Notes
356///
357/// Each element is the min value of signed 256-bit integer for the specified precision which
358/// is encoded to the 76-byte width format of little-endian.
359///
360/// The first element is unused and is inserted so that we can look up using
361/// precision as the index without the need to subtract 1 first.
362/// # Example
363/// ```
364/// # use arrow_buffer::i256;
365/// # use arrow_data::decimal::MIN_DECIMAL256_FOR_EACH_PRECISION;
366/// assert_eq!(MIN_DECIMAL256_FOR_EACH_PRECISION[3], i256::from(-999));
367/// ```
368///
369/// [`i256`]: arrow_buffer::i256
370/// [`Decimal256`]: arrow_schema::DataType::Decimal256
371pub const MIN_DECIMAL256_FOR_EACH_PRECISION: [i256; 77] = [
372    i256::from_i128(0_i128), // unused first element
373    i256::from_le_bytes([
374        247, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
375        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
376    ]),
377    i256::from_le_bytes([
378        157, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
379        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
380    ]),
381    i256::from_le_bytes([
382        25, 252, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
383        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
384    ]),
385    i256::from_le_bytes([
386        241, 216, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
387        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
388    ]),
389    i256::from_le_bytes([
390        97, 121, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
391        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
392    ]),
393    i256::from_le_bytes([
394        193, 189, 240, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
395        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
396    ]),
397    i256::from_le_bytes([
398        129, 105, 103, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
399        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
400    ]),
401    i256::from_le_bytes([
402        1, 31, 10, 250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
403        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
404    ]),
405    i256::from_le_bytes([
406        1, 54, 101, 196, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
407        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
408    ]),
409    i256::from_le_bytes([
410        1, 28, 244, 171, 253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
411        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
412    ]),
413    i256::from_le_bytes([
414        1, 24, 137, 183, 232, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
415        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
416    ]),
417    i256::from_le_bytes([
418        1, 240, 90, 43, 23, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
419        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
420    ]),
421    i256::from_le_bytes([
422        1, 96, 141, 177, 231, 246, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
423        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
424    ]),
425    i256::from_le_bytes([
426        1, 192, 133, 239, 12, 165, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
427        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
428    ]),
429    i256::from_le_bytes([
430        1, 128, 57, 91, 129, 114, 252, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
431        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
432    ]),
433    i256::from_le_bytes([
434        1, 0, 63, 144, 13, 121, 220, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
435        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
436    ]),
437    i256::from_le_bytes([
438        1, 0, 118, 162, 135, 186, 156, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
439        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
440    ]),
441    i256::from_le_bytes([
442        1, 0, 156, 88, 76, 73, 31, 242, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
443        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
444    ]),
445    i256::from_le_bytes([
446        1, 0, 24, 118, 251, 220, 56, 117, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
447        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
448    ]),
449    i256::from_le_bytes([
450        1, 0, 240, 156, 210, 161, 56, 148, 250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
451        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
452    ]),
453    i256::from_le_bytes([
454        1, 0, 96, 33, 58, 82, 54, 202, 201, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
455        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
456    ]),
457    i256::from_le_bytes([
458        1, 0, 192, 77, 69, 54, 31, 230, 225, 253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
459        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
460    ]),
461    i256::from_le_bytes([
462        1, 0, 128, 9, 181, 30, 56, 253, 210, 234, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
463        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
464    ]),
465    i256::from_le_bytes([
466        1, 0, 0, 95, 18, 51, 49, 228, 61, 44, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
467        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
468    ]),
469    i256::from_le_bytes([
470        1, 0, 0, 182, 183, 254, 235, 233, 106, 186, 247, 255, 255, 255, 255, 255, 255, 255, 255,
471        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
472    ]),
473    i256::from_le_bytes([
474        1, 0, 0, 28, 45, 243, 55, 35, 45, 72, 173, 255, 255, 255, 255, 255, 255, 255, 255, 255,
475        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
476    ]),
477    i256::from_le_bytes([
478        1, 0, 0, 24, 195, 127, 47, 96, 195, 209, 196, 252, 255, 255, 255, 255, 255, 255, 255, 255,
479        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
480    ]),
481    i256::from_le_bytes([
482        1, 0, 0, 240, 158, 253, 218, 193, 161, 49, 176, 223, 255, 255, 255, 255, 255, 255, 255,
483        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
484    ]),
485    i256::from_le_bytes([
486        1, 0, 0, 96, 53, 232, 141, 146, 81, 240, 225, 188, 254, 255, 255, 255, 255, 255, 255, 255,
487        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
488    ]),
489    i256::from_le_bytes([
490        1, 0, 0, 192, 21, 18, 139, 185, 47, 99, 211, 96, 243, 255, 255, 255, 255, 255, 255, 255,
491        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
492    ]),
493    i256::from_le_bytes([
494        1, 0, 0, 128, 217, 180, 110, 63, 221, 223, 65, 200, 129, 255, 255, 255, 255, 255, 255, 255,
495        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
496    ]),
497    i256::from_le_bytes([
498        1, 0, 0, 0, 127, 16, 83, 122, 164, 190, 146, 210, 17, 251, 255, 255, 255, 255, 255, 255,
499        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
500    ]),
501    i256::from_le_bytes([
502        1, 0, 0, 0, 246, 164, 62, 199, 108, 114, 187, 57, 178, 206, 255, 255, 255, 255, 255, 255,
503        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
504    ]),
505    i256::from_le_bytes([
506        1, 0, 0, 0, 156, 113, 114, 200, 63, 120, 82, 65, 246, 18, 254, 255, 255, 255, 255, 255,
507        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
508    ]),
509    i256::from_le_bytes([
510        1, 0, 0, 0, 24, 112, 120, 212, 125, 178, 56, 141, 158, 189, 236, 255, 255, 255, 255, 255,
511        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
512    ]),
513    i256::from_le_bytes([
514        1, 0, 0, 0, 240, 96, 180, 76, 234, 248, 54, 132, 49, 104, 63, 255, 255, 255, 255, 255, 255,
515        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
516    ]),
517    i256::from_le_bytes([
518        1, 0, 0, 0, 96, 201, 11, 255, 38, 185, 37, 42, 239, 17, 122, 248, 255, 255, 255, 255, 255,
519        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
520    ]),
521    i256::from_le_bytes([
522        1, 0, 0, 0, 192, 221, 117, 246, 133, 59, 121, 165, 87, 179, 196, 180, 255, 255, 255, 255,
523        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
524    ]),
525    i256::from_le_bytes([
526        1, 0, 0, 0, 128, 169, 154, 160, 59, 83, 188, 118, 108, 1, 175, 15, 253, 255, 255, 255, 255,
527        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
528    ]),
529    i256::from_le_bytes([
530        1, 0, 0, 0, 0, 159, 10, 70, 84, 64, 91, 163, 60, 14, 214, 156, 226, 255, 255, 255, 255,
531        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
532    ]),
533    i256::from_le_bytes([
534        1, 0, 0, 0, 0, 54, 106, 188, 74, 131, 144, 97, 94, 142, 92, 32, 218, 254, 255, 255, 255,
535        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
536    ]),
537    i256::from_le_bytes([
538        1, 0, 0, 0, 0, 28, 38, 92, 235, 32, 165, 207, 175, 143, 157, 67, 133, 244, 255, 255, 255,
539        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
540    ]),
541    i256::from_le_bytes([
542        1, 0, 0, 0, 0, 24, 125, 153, 49, 73, 115, 28, 222, 156, 39, 164, 52, 141, 255, 255, 255,
543        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
544    ]),
545    i256::from_le_bytes([
546        1, 0, 0, 0, 0, 240, 226, 254, 239, 219, 128, 28, 173, 32, 140, 105, 14, 132, 251, 255, 255,
547        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
548    ]),
549    i256::from_le_bytes([
550        1, 0, 0, 0, 0, 96, 221, 244, 95, 151, 8, 29, 195, 70, 121, 31, 144, 40, 211, 255, 255, 255,
551        255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
552    ]),
553    i256::from_le_bytes([
554        1, 0, 0, 0, 0, 192, 165, 144, 191, 233, 85, 34, 159, 195, 188, 58, 161, 149, 63, 254, 255,
555        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
556    ]),
557    i256::from_le_bytes([
558        1, 0, 0, 0, 0, 128, 121, 166, 123, 33, 91, 87, 55, 164, 95, 75, 76, 216, 123, 238, 255,
559        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
560    ]),
561    i256::from_le_bytes([
562        1, 0, 0, 0, 0, 0, 191, 128, 212, 78, 143, 105, 41, 106, 188, 241, 250, 114, 214, 80, 255,
563        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
564    ]),
565    i256::from_le_bytes([
566        1, 0, 0, 0, 0, 0, 118, 7, 77, 20, 153, 31, 158, 37, 92, 113, 205, 125, 96, 40, 249, 255,
567        255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
568    ]),
569    i256::from_le_bytes([
570        1, 0, 0, 0, 0, 0, 156, 74, 2, 203, 250, 59, 45, 120, 153, 109, 6, 234, 196, 147, 187, 255,
571        255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
572    ]),
573    i256::from_le_bytes([
574        1, 0, 0, 0, 0, 0, 24, 234, 22, 238, 203, 87, 196, 177, 254, 71, 64, 36, 177, 197, 83, 253,
575        255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
576    ]),
577    i256::from_le_bytes([
578        1, 0, 0, 0, 0, 0, 240, 36, 229, 76, 247, 109, 171, 241, 242, 207, 130, 106, 235, 184, 69,
579        229, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
580    ]),
581    i256::from_le_bytes([
582        1, 0, 0, 0, 0, 0, 96, 113, 243, 0, 169, 75, 178, 112, 125, 31, 28, 41, 50, 57, 185, 244,
583        254, 255, 255, 255, 255, 255, 255, 255, 255, 255,
584    ]),
585    i256::from_le_bytes([
586        1, 0, 0, 0, 0, 0, 192, 109, 130, 9, 154, 244, 246, 102, 230, 58, 25, 155, 245, 59, 60, 143,
587        245, 255, 255, 255, 255, 255, 255, 255, 255, 255,
588    ]),
589    i256::from_le_bytes([
590        1, 0, 0, 0, 0, 0, 128, 73, 24, 95, 4, 142, 165, 5, 0, 77, 252, 14, 152, 87, 90, 152, 151,
591        255, 255, 255, 255, 255, 255, 255, 255, 255,
592    ]),
593    i256::from_le_bytes([
594        1, 0, 0, 0, 0, 0, 0, 223, 242, 182, 43, 140, 119, 56, 0, 2, 219, 149, 240, 107, 135, 243,
595        235, 251, 255, 255, 255, 255, 255, 255, 255, 255,
596    ]),
597    i256::from_le_bytes([
598        1, 0, 0, 0, 0, 0, 0, 182, 124, 37, 181, 121, 171, 52, 2, 20, 142, 218, 101, 55, 74, 131,
599        55, 215, 255, 255, 255, 255, 255, 255, 255, 255,
600    ]),
601    i256::from_le_bytes([
602        1, 0, 0, 0, 0, 0, 0, 28, 223, 118, 19, 193, 178, 14, 22, 200, 140, 137, 250, 41, 230, 32,
603        43, 104, 254, 255, 255, 255, 255, 255, 255, 255,
604    ]),
605    i256::from_le_bytes([
606        1, 0, 0, 0, 0, 0, 0, 24, 183, 164, 194, 138, 251, 146, 220, 208, 127, 95, 201, 163, 253,
607        72, 175, 17, 240, 255, 255, 255, 255, 255, 255, 255,
608    ]),
609    i256::from_le_bytes([
610        1, 0, 0, 0, 0, 0, 0, 240, 38, 111, 154, 107, 211, 189, 157, 40, 254, 186, 221, 101, 232,
611        217, 216, 176, 96, 255, 255, 255, 255, 255, 255, 255,
612    ]),
613    i256::from_le_bytes([
614        1, 0, 0, 0, 0, 0, 0, 96, 133, 87, 8, 52, 66, 106, 41, 150, 237, 77, 169, 250, 19, 131, 120,
615        232, 198, 249, 255, 255, 255, 255, 255, 255,
616    ]),
617    i256::from_le_bytes([
618        1, 0, 0, 0, 0, 0, 0, 192, 53, 107, 83, 8, 150, 38, 158, 221, 71, 11, 157, 202, 199, 30,
619        181, 20, 197, 193, 255, 255, 255, 255, 255, 255,
620    ]),
621    i256::from_le_bytes([
622        1, 0, 0, 0, 0, 0, 0, 128, 25, 48, 66, 83, 220, 129, 45, 168, 206, 112, 34, 234, 205, 51,
623        19, 207, 178, 145, 253, 255, 255, 255, 255, 255,
624    ]),
625    i256::from_le_bytes([
626        1, 0, 0, 0, 0, 0, 0, 0, 255, 224, 149, 64, 155, 18, 199, 145, 18, 104, 88, 37, 11, 6, 192,
627        22, 252, 176, 231, 255, 255, 255, 255, 255,
628    ]),
629    i256::from_le_bytes([
630        1, 0, 0, 0, 0, 0, 0, 0, 246, 201, 218, 133, 16, 186, 198, 177, 185, 16, 116, 117, 111, 60,
631        128, 227, 216, 233, 12, 255, 255, 255, 255, 255,
632    ]),
633    i256::from_le_bytes([
634        1, 0, 0, 0, 0, 0, 0, 0, 156, 227, 139, 58, 165, 68, 195, 241, 64, 167, 136, 150, 90, 92, 2,
635        227, 120, 34, 129, 246, 255, 255, 255, 255,
636    ]),
637    i256::from_le_bytes([
638        1, 0, 0, 0, 0, 0, 0, 0, 24, 228, 118, 73, 116, 174, 160, 113, 137, 136, 86, 225, 137, 155,
639        23, 222, 184, 88, 11, 161, 255, 255, 255, 255,
640    ]),
641    i256::from_le_bytes([
642        1, 0, 0, 0, 0, 0, 0, 0, 240, 232, 164, 222, 138, 208, 70, 112, 94, 85, 97, 205, 98, 19,
643        236, 172, 56, 119, 113, 74, 252, 255, 255, 255,
644    ]),
645    i256::from_le_bytes([
646        1, 0, 0, 0, 0, 0, 0, 0, 96, 25, 113, 178, 108, 37, 196, 98, 176, 85, 205, 5, 220, 193, 56,
647        193, 54, 168, 110, 232, 218, 255, 255, 255,
648    ]),
649    i256::from_le_bytes([
650        1, 0, 0, 0, 0, 0, 0, 0, 192, 253, 106, 248, 62, 118, 169, 219, 227, 88, 5, 58, 152, 146,
651        55, 140, 35, 146, 82, 20, 141, 254, 255, 255,
652    ]),
653    i256::from_le_bytes([
654        1, 0, 0, 0, 0, 0, 0, 0, 128, 233, 45, 180, 117, 158, 158, 148, 230, 120, 53, 68, 242, 185,
655        43, 122, 99, 181, 57, 203, 130, 241, 255, 255,
656    ]),
657    i256::from_le_bytes([
658        1, 0, 0, 0, 0, 0, 0, 0, 0, 31, 203, 9, 153, 48, 50, 206, 1, 185, 22, 170, 118, 67, 181,
659        197, 226, 21, 65, 240, 27, 111, 255, 255,
660    ]),
661    i256::from_le_bytes([
662        1, 0, 0, 0, 0, 0, 0, 0, 0, 54, 239, 97, 250, 229, 245, 13, 18, 58, 227, 164, 162, 162, 20,
663        185, 219, 218, 138, 98, 23, 87, 250, 255,
664    ]),
665    i256::from_le_bytes([
666        1, 0, 0, 0, 0, 0, 0, 0, 0, 28, 88, 211, 199, 251, 154, 139, 180, 68, 224, 112, 90, 90, 206,
667        58, 149, 140, 108, 217, 233, 102, 199, 255,
668    ]),
669    i256::from_le_bytes([
670        1, 0, 0, 0, 0, 0, 0, 0, 0, 24, 113, 65, 206, 213, 13, 116, 13, 175, 194, 104, 136, 135, 15,
671        76, 212, 125, 61, 126, 34, 5, 202, 253,
672    ]),
673    i256::from_le_bytes([
674        1, 0, 0, 0, 0, 0, 0, 0, 0, 240, 106, 142, 14, 90, 138, 136, 134, 214, 154, 23, 84, 75, 155,
675        248, 74, 234, 102, 238, 88, 51, 228, 233,
676    ]),
677];
678
679/// `MAX_DECIMAL128_FOR_EACH_PRECISION[p]` holds the maximum `i128` value that can
680/// be stored in [`Decimal128`] value of precision `p`.
681///
682/// # Notes
683///
684/// The first element is unused and is inserted so that we can look up using
685/// precision as the index without the need to subtract 1 first.
686///
687/// # Example
688/// ```
689/// # use arrow_data::decimal::MAX_DECIMAL128_FOR_EACH_PRECISION;
690/// assert_eq!(MAX_DECIMAL128_FOR_EACH_PRECISION[3], 999);
691/// ```
692///
693/// [`Decimal128`]: arrow_schema::DataType::Decimal128
694pub const MAX_DECIMAL128_FOR_EACH_PRECISION: [i128; 39] = [
695    0, // unused first element
696    9,
697    99,
698    999,
699    9999,
700    99999,
701    999999,
702    9999999,
703    99999999,
704    999999999,
705    9999999999,
706    99999999999,
707    999999999999,
708    9999999999999,
709    99999999999999,
710    999999999999999,
711    9999999999999999,
712    99999999999999999,
713    999999999999999999,
714    9999999999999999999,
715    99999999999999999999,
716    999999999999999999999,
717    9999999999999999999999,
718    99999999999999999999999,
719    999999999999999999999999,
720    9999999999999999999999999,
721    99999999999999999999999999,
722    999999999999999999999999999,
723    9999999999999999999999999999,
724    99999999999999999999999999999,
725    999999999999999999999999999999,
726    9999999999999999999999999999999,
727    99999999999999999999999999999999,
728    999999999999999999999999999999999,
729    9999999999999999999999999999999999,
730    99999999999999999999999999999999999,
731    999999999999999999999999999999999999,
732    9999999999999999999999999999999999999,
733    99999999999999999999999999999999999999,
734];
735
736/// `MIN_DECIMAL_FOR_EACH_PRECISION[p]` holds the minimum `i128` value that can
737/// be stored in a [`Decimal128`] value of precision `p`.
738///
739/// # Notes
740///
741/// The first element is unused and is inserted so that we can look up using
742/// precision as the index without the need to subtract 1 first.
743///
744/// # Example
745/// ```
746/// # use arrow_data::decimal::MIN_DECIMAL128_FOR_EACH_PRECISION;
747/// assert_eq!(MIN_DECIMAL128_FOR_EACH_PRECISION[3], -999);
748/// ```
749///
750/// [`Decimal128`]: arrow_schema::DataType::Decimal128
751pub const MIN_DECIMAL128_FOR_EACH_PRECISION: [i128; 39] = [
752    0, // unused first element
753    -9,
754    -99,
755    -999,
756    -9999,
757    -99999,
758    -999999,
759    -9999999,
760    -99999999,
761    -999999999,
762    -9999999999,
763    -99999999999,
764    -999999999999,
765    -9999999999999,
766    -99999999999999,
767    -999999999999999,
768    -9999999999999999,
769    -99999999999999999,
770    -999999999999999999,
771    -9999999999999999999,
772    -99999999999999999999,
773    -999999999999999999999,
774    -9999999999999999999999,
775    -99999999999999999999999,
776    -999999999999999999999999,
777    -9999999999999999999999999,
778    -99999999999999999999999999,
779    -999999999999999999999999999,
780    -9999999999999999999999999999,
781    -99999999999999999999999999999,
782    -999999999999999999999999999999,
783    -9999999999999999999999999999999,
784    -99999999999999999999999999999999,
785    -999999999999999999999999999999999,
786    -9999999999999999999999999999999999,
787    -99999999999999999999999999999999999,
788    -999999999999999999999999999999999999,
789    -9999999999999999999999999999999999999,
790    -99999999999999999999999999999999999999,
791];
792
793/// `MAX_DECIMAL64_FOR_EACH_PRECISION[p]` holds the maximum `i64` value that can
794/// be stored in [`Decimal64`] value of precision `p`.
795///
796/// # Notes
797///
798/// The first element is unused and is inserted so that we can look up using
799/// precision as the index without the need to subtract 1 first.
800///
801/// # Example
802/// ```
803/// # use arrow_data::decimal::MAX_DECIMAL64_FOR_EACH_PRECISION;
804/// assert_eq!(MAX_DECIMAL64_FOR_EACH_PRECISION[3], 999);
805/// ```
806///
807/// [`Decimal64`]: arrow_schema::DataType::Decimal64
808pub const MAX_DECIMAL64_FOR_EACH_PRECISION: [i64; 19] = [
809    0, // unused first element
810    9,
811    99,
812    999,
813    9999,
814    99999,
815    999999,
816    9999999,
817    99999999,
818    999999999,
819    9999999999,
820    99999999999,
821    999999999999,
822    9999999999999,
823    99999999999999,
824    999999999999999,
825    9999999999999999,
826    99999999999999999,
827    999999999999999999,
828];
829
830/// `MIN_DECIMAL64_FOR_EACH_PRECISION[p]` holds the minimum `i64` value that can
831/// be stored in a [`Decimal64`] value of precision `p`.
832///
833/// # Notes
834///
835/// The first element is unused and is inserted so that we can look up using
836/// precision as the index without the need to subtract 1 first.
837///
838/// # Example
839/// ```
840/// # use arrow_data::decimal::MIN_DECIMAL64_FOR_EACH_PRECISION;
841/// assert_eq!(MIN_DECIMAL64_FOR_EACH_PRECISION[3], -999);
842/// ```
843///
844/// [`Decimal64`]: arrow_schema::DataType::Decimal64
845pub const MIN_DECIMAL64_FOR_EACH_PRECISION: [i64; 19] = [
846    0, // unused first element
847    -9,
848    -99,
849    -999,
850    -9999,
851    -99999,
852    -999999,
853    -9999999,
854    -99999999,
855    -999999999,
856    -9999999999,
857    -99999999999,
858    -999999999999,
859    -9999999999999,
860    -99999999999999,
861    -999999999999999,
862    -9999999999999999,
863    -99999999999999999,
864    -999999999999999999,
865];
866
867/// `MAX_DECIMAL32_FOR_EACH_PRECISION[p]` holds the maximum `i32` value that can
868/// be stored in [`Decimal32`] value of precision `p`.
869///
870/// # Notes
871///
872/// The first element is unused and is inserted so that we can look up using
873/// precision as the index without the need to subtract 1 first.
874///
875/// # Example
876/// ```
877/// # use arrow_data::decimal::MAX_DECIMAL32_FOR_EACH_PRECISION;
878/// assert_eq!(MAX_DECIMAL32_FOR_EACH_PRECISION[3], 999);
879/// ```
880///
881/// [`Decimal32`]: arrow_schema::DataType::Decimal32
882pub const MAX_DECIMAL32_FOR_EACH_PRECISION: [i32; 10] = [
883    0, // unused first element
884    9, 99, 999, 9999, 99999, 999999, 9999999, 99999999, 999999999,
885];
886
887/// `MIN_DECIMAL32_FOR_EACH_PRECISION[p]` holds the minimum value that can
888/// be stored in a [`Decimal32`] value of precision `p`.
889///
890/// # Notes
891///
892/// The first element is unused and is inserted so that we can look up using
893/// precision as the index without the need to subtract 1 first.
894///
895/// # Example
896/// ```
897/// # use arrow_data::decimal::MIN_DECIMAL32_FOR_EACH_PRECISION;
898/// assert_eq!(MIN_DECIMAL32_FOR_EACH_PRECISION[3], -999);
899/// ```
900///
901/// [`Decimal32`]: arrow_schema::DataType::Decimal32
902pub const MIN_DECIMAL32_FOR_EACH_PRECISION: [i32; 10] = [
903    0, // unused first element
904    -9, -99, -999, -9999, -99999, -999999, -9999999, -99999999, -999999999,
905];
906
907/// Validates that the specified `i32` value can be properly
908/// interpreted as a [`Decimal32`] number with precision `precision`
909///
910/// [`Decimal32`]: arrow_schema::DataType::Decimal32
911#[inline]
912pub fn validate_decimal32_precision(
913    value: i32,
914    precision: u8,
915    scale: i8,
916) -> Result<(), ArrowError> {
917    if precision > DECIMAL32_MAX_PRECISION {
918        return Err(ArrowError::InvalidArgumentError(format!(
919            "Max precision of a Decimal32 is {DECIMAL32_MAX_PRECISION}, but got {precision}",
920        )));
921    }
922    if value > MAX_DECIMAL32_FOR_EACH_PRECISION[precision as usize] {
923        let unscaled_value = format_decimal(value, scale);
924        let unscale_max_value =
925            format_decimal(MAX_DECIMAL32_FOR_EACH_PRECISION[precision as usize], scale);
926        Err(ArrowError::InvalidArgumentError(format!(
927            "{unscaled_value} is too large to store in a Decimal32 of precision {precision}. Max is {unscale_max_value}"
928        )))
929    } else if value < MIN_DECIMAL32_FOR_EACH_PRECISION[precision as usize] {
930        let unscaled_value = format_decimal(value, scale);
931        let unscale_min_value =
932            format_decimal(MIN_DECIMAL32_FOR_EACH_PRECISION[precision as usize], scale);
933        Err(ArrowError::InvalidArgumentError(format!(
934            "{unscaled_value} is too small to store in a Decimal32 of precision {precision}. Min is {unscale_min_value}"
935        )))
936    } else {
937        Ok(())
938    }
939}
940
941/// Returns true if the specified `i32` value can be properly
942/// interpreted as a [`Decimal32`] number with precision `precision`
943///
944/// [`Decimal32`]: arrow_schema::DataType::Decimal32
945#[inline]
946pub fn is_validate_decimal32_precision(value: i32, precision: u8) -> bool {
947    precision <= DECIMAL32_MAX_PRECISION
948        && value >= MIN_DECIMAL32_FOR_EACH_PRECISION[precision as usize]
949        && value <= MAX_DECIMAL32_FOR_EACH_PRECISION[precision as usize]
950}
951
952/// Validates that the specified `i64` value can be properly
953/// interpreted as a [`Decimal64`] number with precision `precision`
954///
955/// [`Decimal64`]: arrow_schema::DataType::Decimal64
956#[inline]
957pub fn validate_decimal64_precision(
958    value: i64,
959    precision: u8,
960    scale: i8,
961) -> Result<(), ArrowError> {
962    if precision > DECIMAL64_MAX_PRECISION {
963        return Err(ArrowError::InvalidArgumentError(format!(
964            "Max precision of a Decimal64 is {DECIMAL64_MAX_PRECISION}, but got {precision}",
965        )));
966    }
967    if value > MAX_DECIMAL64_FOR_EACH_PRECISION[precision as usize] {
968        let unscaled_value = format_decimal(value, scale);
969        let unscaled_max_value =
970            format_decimal(MAX_DECIMAL64_FOR_EACH_PRECISION[precision as usize], scale);
971        Err(ArrowError::InvalidArgumentError(format!(
972            "{unscaled_value} is too large to store in a Decimal64 of precision {precision}. Max is {unscaled_max_value}"
973        )))
974    } else if value < MIN_DECIMAL64_FOR_EACH_PRECISION[precision as usize] {
975        let unscaled_value = format_decimal(value, scale);
976        let unscaled_min_value =
977            format_decimal(MIN_DECIMAL64_FOR_EACH_PRECISION[precision as usize], scale);
978        Err(ArrowError::InvalidArgumentError(format!(
979            "{unscaled_value} is too small to store in a Decimal64 of precision {precision}. Min is {unscaled_min_value}"
980        )))
981    } else {
982        Ok(())
983    }
984}
985
986/// Returns true if the specified `i64` value can be properly
987/// interpreted as a [`Decimal64`] number with precision `precision`
988///
989/// [`Decimal64`]: arrow_schema::DataType::Decimal64
990#[inline]
991pub fn is_validate_decimal64_precision(value: i64, precision: u8) -> bool {
992    precision <= DECIMAL64_MAX_PRECISION
993        && value >= MIN_DECIMAL64_FOR_EACH_PRECISION[precision as usize]
994        && value <= MAX_DECIMAL64_FOR_EACH_PRECISION[precision as usize]
995}
996
997/// Validates that the specified `i128` value can be properly
998/// interpreted as a [`Decimal128`] number with precision `precision`
999///
1000/// [`Decimal128`]: arrow_schema::DataType::Decimal128
1001#[inline]
1002pub fn validate_decimal_precision(value: i128, precision: u8, scale: i8) -> Result<(), ArrowError> {
1003    if precision > DECIMAL128_MAX_PRECISION {
1004        return Err(ArrowError::InvalidArgumentError(format!(
1005            "Max precision of a Decimal128 is {DECIMAL128_MAX_PRECISION}, but got {precision}",
1006        )));
1007    }
1008    if value > MAX_DECIMAL128_FOR_EACH_PRECISION[precision as usize] {
1009        let unscaled_value = format_decimal(value, scale);
1010        let unscaled_max_value =
1011            format_decimal(MAX_DECIMAL128_FOR_EACH_PRECISION[precision as usize], scale);
1012        Err(ArrowError::InvalidArgumentError(format!(
1013            "{unscaled_value} is too large to store in a Decimal128 of precision {precision}. Max is {unscaled_max_value}"
1014        )))
1015    } else if value < MIN_DECIMAL128_FOR_EACH_PRECISION[precision as usize] {
1016        let unscaled_value = format_decimal(value, scale);
1017        let unscaled_min_value =
1018            format_decimal(MIN_DECIMAL128_FOR_EACH_PRECISION[precision as usize], scale);
1019        Err(ArrowError::InvalidArgumentError(format!(
1020            "{unscaled_value} is too small to store in a Decimal128 of precision {precision}. Min is {unscaled_min_value}"
1021        )))
1022    } else {
1023        Ok(())
1024    }
1025}
1026
1027/// Returns true if the specified `i128` value can be properly
1028/// interpreted as a [`Decimal128`] number with precision `precision`
1029///
1030/// [`Decimal128`]: arrow_schema::DataType::Decimal128
1031#[inline]
1032pub fn is_validate_decimal_precision(value: i128, precision: u8) -> bool {
1033    precision <= DECIMAL128_MAX_PRECISION
1034        && value >= MIN_DECIMAL128_FOR_EACH_PRECISION[precision as usize]
1035        && value <= MAX_DECIMAL128_FOR_EACH_PRECISION[precision as usize]
1036}
1037
1038/// Validates that the specified `i256` of value can be properly
1039/// interpreted as a [`Decimal256`] number with precision `precision`
1040///
1041/// [`Decimal256`]: arrow_schema::DataType::Decimal256
1042#[inline]
1043pub fn validate_decimal256_precision(
1044    value: i256,
1045    precision: u8,
1046    scale: i8,
1047) -> Result<(), ArrowError> {
1048    if precision > DECIMAL256_MAX_PRECISION {
1049        return Err(ArrowError::InvalidArgumentError(format!(
1050            "Max precision of a Decimal256 is {DECIMAL256_MAX_PRECISION}, but got {precision}",
1051        )));
1052    }
1053
1054    if value > MAX_DECIMAL256_FOR_EACH_PRECISION[precision as usize] {
1055        let unscaled_value = format_decimal(value, scale);
1056        let unscaled_max_value =
1057            format_decimal(MAX_DECIMAL256_FOR_EACH_PRECISION[precision as usize], scale);
1058        Err(ArrowError::InvalidArgumentError(format!(
1059            "{unscaled_value} is too large to store in a Decimal256 of precision {precision}. Max is {unscaled_max_value}"
1060        )))
1061    } else if value < MIN_DECIMAL256_FOR_EACH_PRECISION[precision as usize] {
1062        let unscaled_value = format_decimal(value, scale);
1063        let unscaled_min_value =
1064            format_decimal(MIN_DECIMAL256_FOR_EACH_PRECISION[precision as usize], scale);
1065        Err(ArrowError::InvalidArgumentError(format!(
1066            "{unscaled_value} is too small to store in a Decimal256 of precision {precision}. Min is {unscaled_min_value}"
1067        )))
1068    } else {
1069        Ok(())
1070    }
1071}
1072
1073/// Return true if the specified `i256` value can be properly
1074/// interpreted as a [`Decimal256`] number with precision `precision`
1075///
1076/// [`Decimal256`]: arrow_schema::DataType::Decimal256
1077#[inline]
1078pub fn is_validate_decimal256_precision(value: i256, precision: u8) -> bool {
1079    precision <= DECIMAL256_MAX_PRECISION
1080        && value >= MIN_DECIMAL256_FOR_EACH_PRECISION[precision as usize]
1081        && value <= MAX_DECIMAL256_FOR_EACH_PRECISION[precision as usize]
1082}
1083
1084#[inline]
1085/// Formats a decimal string given the scale.
1086///
1087/// The value is always formatted in full: `_precision` is unused and retained
1088/// only for API compatibility.
1089pub fn format_decimal_str(value_str: &str, _precision: usize, scale: i8) -> String {
1090    format_decimal_str_internal(value_str, scale)
1091}
1092
1093/// The native value of a decimal type: `i32`, `i64`, `i128` or `i256`
1094pub trait DecimalNativeType: Display + sealed::DecimalNativeTypeSealed {}
1095
1096mod sealed {
1097    pub trait DecimalNativeTypeSealed {}
1098}
1099
1100macro_rules! decimal_native {
1101    ($($t:ty),+) => {
1102        $(
1103            impl sealed::DecimalNativeTypeSealed for $t {}
1104            impl DecimalNativeType for $t {}
1105        )+
1106    };
1107}
1108
1109decimal_native!(i32, i64, i128, i256);
1110
1111/// Formats the unscaled decimal `value` with `scale` fractional digits: the
1112/// decimal point is inserted `scale` digits from the right, with leading
1113/// zeros as needed, and a negative scale appends zeros instead. The value is
1114/// always formatted in full, whatever its precision.
1115pub fn format_decimal<V: DecimalNativeType>(value: V, scale: i8) -> String {
1116    format_decimal_str_internal(DigitBuffer::from_value(&value).as_str(), scale)
1117}
1118
1119/// Like [`format_decimal`], but writes the result to `f` instead of returning
1120/// a new `String`.
1121pub fn write_decimal<V: DecimalNativeType>(
1122    f: &mut dyn Write,
1123    value: V,
1124    scale: i8,
1125) -> std::fmt::Result {
1126    write_decimal_str(f, DigitBuffer::from_value(&value).as_str(), scale)
1127}
1128
1129/// Formats `value_str` as [`write_decimal_str`] does, into a `String` with
1130/// enough capacity to avoid reallocation
1131fn format_decimal_str_internal(value_str: &str, scale: i8) -> String {
1132    let mut out = String::with_capacity(value_str.len() + scale.unsigned_abs() as usize + 2);
1133    write_decimal_str(&mut out, value_str, scale).expect("writing to a String cannot fail");
1134    out
1135}
1136
1137/// The length of the longest decimal native value when formatted: `i256::MIN`
1138/// has 77 digits and a sign
1139const MAX_DECIMAL_VALUE_LEN: usize = 78;
1140
1141/// The formatted digits of a decimal native value, with its sign
1142struct DigitBuffer {
1143    bytes: [u8; MAX_DECIMAL_VALUE_LEN],
1144    len: usize,
1145}
1146
1147impl DigitBuffer {
1148    /// Formats `value`
1149    fn from_value(value: &dyn DecimalNativeType) -> Self {
1150        let mut buf = Self {
1151            bytes: [0; MAX_DECIMAL_VALUE_LEN],
1152            len: 0,
1153        };
1154        write!(buf, "{value}").expect("a decimal native value fits the digit buffer");
1155        buf
1156    }
1157
1158    fn as_str(&self) -> &str {
1159        // `write_str` copies complete strings, so the bytes are valid UTF-8
1160        std::str::from_utf8(&self.bytes[..self.len]).expect("DigitBuffer contains valid UTF-8")
1161    }
1162}
1163
1164impl Write for DigitBuffer {
1165    fn write_str(&mut self, s: &str) -> std::fmt::Result {
1166        let end = self.len + s.len();
1167        let target = self.bytes.get_mut(self.len..end).ok_or(std::fmt::Error)?;
1168        target.copy_from_slice(s.as_bytes());
1169        self.len = end;
1170        Ok(())
1171    }
1172}
1173
1174/// Writes `value_str`, the digits of an unscaled decimal value with an optional
1175/// leading `-`, to `f` as a decimal with `scale` fractional digits: the decimal
1176/// point is inserted `scale` digits from the right, with leading zeros as
1177/// needed, and a negative scale appends zeros instead. The value is always
1178/// written in full, whatever its precision.
1179fn write_decimal_str(f: &mut dyn Write, value_str: &str, scale: i8) -> std::fmt::Result {
1180    let (sign, digits) = match value_str.strip_prefix('-') {
1181        Some(digits) => ("-", digits),
1182        None => ("", value_str),
1183    };
1184
1185    if scale == 0 {
1186        f.write_str(value_str)
1187    } else if scale < 0 {
1188        f.write_str(value_str)?;
1189        // Zero must not be zero-padded ("000" is not a valid number)
1190        if digits != "0" {
1191            for _ in 0..scale.unsigned_abs() {
1192                f.write_char('0')?;
1193            }
1194        }
1195        Ok(())
1196    } else if digits.len() > scale as usize {
1197        // The decimal point is in the middle of the digits
1198        let (whole, fraction) = value_str.split_at(value_str.len() - scale as usize);
1199        f.write_str(whole)?;
1200        f.write_char('.')?;
1201        f.write_str(fraction)
1202    } else {
1203        // The digits are all fractional and may need leading zeros
1204        f.write_str(sign)?;
1205        f.write_str("0.")?;
1206        for _ in digits.len()..scale as usize {
1207            f.write_char('0')?;
1208        }
1209        f.write_str(digits)
1210    }
1211}
1212
1213#[cfg(test)]
1214mod tests {
1215    use super::*;
1216
1217    #[test]
1218    fn test_format_decimal() {
1219        assert_eq!(format_decimal(12345_i32, 2), "123.45");
1220        assert_eq!(format_decimal(-5_i64, 3), "-0.005");
1221        assert_eq!(format_decimal(0_i128, -2), "0");
1222        assert_eq!(format_decimal(i32::MIN, 9), "-2.147483648");
1223        assert_eq!(format_decimal(i64::MIN, 18), "-9.223372036854775808");
1224        assert_eq!(
1225            format_decimal(i128::MIN, 38),
1226            "-1.70141183460469231731687303715884105728"
1227        );
1228        assert_eq!(
1229            format_decimal(i256::MIN, 0),
1230            "-57896044618658097711785492504343953926634992332820282019728792003956564819968"
1231        );
1232        assert_eq!(
1233            format_decimal(i256::MAX, 76),
1234            "5.7896044618658097711785492504343953926634992332820282019728792003956564819967"
1235        );
1236    }
1237
1238    #[test]
1239    fn test_format_decimal_str() {
1240        assert_eq!(format_decimal_str("12345", 7, 0), "12345");
1241        assert_eq!(format_decimal_str("12345", 7, 2), "123.45");
1242        assert_eq!(format_decimal_str("-12345", 7, 2), "-123.45");
1243        assert_eq!(format_decimal_str("45", 7, 3), "0.045");
1244        assert_eq!(format_decimal_str("-45", 7, 3), "-0.045");
1245        assert_eq!(format_decimal_str("0", 7, 2), "0.00");
1246        assert_eq!(format_decimal_str("12345", 7, 5), "0.12345");
1247
1248        // negative scales multiply the value by 10^|scale|
1249        assert_eq!(format_decimal_str("12", 7, -2), "1200");
1250        assert_eq!(format_decimal_str("-12", 7, -2), "-1200");
1251        // a zero value is not padded
1252        // https://github.com/apache/arrow-rs/issues/10865
1253        assert_eq!(format_decimal_str("0", 7, -2), "0");
1254
1255        // values exceeding the declared precision are still formatted in full
1256        // https://github.com/apache/arrow-rs/issues/10866
1257        assert_eq!(format_decimal_str("12345", 3, 1), "1234.5");
1258        assert_eq!(format_decimal_str("12345", 3, 3), "12.345");
1259        assert_eq!(format_decimal_str("-12345", 3, 3), "-12.345");
1260        assert_eq!(format_decimal_str("12345", 2, 4), "1.2345");
1261    }
1262}