Skip to main content

arrow_data/
decimal.rs

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