Coverage Report

Created: 2025-11-17 14:14

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/Users/andrewlamb/Software/arrow-rs/arrow-buffer/src/bigint/mod.rs
Line
Count
Source
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
use crate::arith::derive_arith;
19
use crate::bigint::div::div_rem;
20
use num_bigint::BigInt;
21
use num_traits::{FromPrimitive, ToPrimitive, cast::AsPrimitive};
22
use std::cmp::Ordering;
23
use std::num::ParseIntError;
24
use std::ops::{BitAnd, BitOr, BitXor, Neg, Shl, Shr};
25
use std::str::FromStr;
26
27
mod div;
28
29
/// An opaque error similar to [`std::num::ParseIntError`]
30
#[derive(Debug)]
31
pub struct ParseI256Error {}
32
33
impl From<ParseIntError> for ParseI256Error {
34
0
    fn from(_: ParseIntError) -> Self {
35
0
        Self {}
36
0
    }
37
}
38
39
impl std::fmt::Display for ParseI256Error {
40
0
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
41
0
        write!(f, "Failed to parse as i256")
42
0
    }
43
}
44
impl std::error::Error for ParseI256Error {}
45
46
/// Error returned by i256::DivRem
47
enum DivRemError {
48
    /// Division by zero
49
    DivideByZero,
50
    /// Division overflow
51
    DivideOverflow,
52
}
53
54
/// A signed 256-bit integer
55
#[allow(non_camel_case_types)]
56
#[derive(Copy, Clone, Default, Eq, PartialEq, Hash)]
57
#[repr(C)]
58
pub struct i256 {
59
    low: u128,
60
    high: i128,
61
}
62
63
impl std::fmt::Debug for i256 {
64
0
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
65
0
        write!(f, "{self}")
66
0
    }
67
}
68
69
impl std::fmt::Display for i256 {
70
0
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
71
0
        write!(f, "{}", BigInt::from_signed_bytes_le(&self.to_le_bytes()))
72
0
    }
73
}
74
75
impl FromStr for i256 {
76
    type Err = ParseI256Error;
77
78
0
    fn from_str(s: &str) -> Result<Self, Self::Err> {
79
        // i128 can store up to 38 decimal digits
80
0
        if s.len() <= 38 {
81
0
            return Ok(Self::from_i128(i128::from_str(s)?));
82
0
        }
83
84
0
        let (negative, s) = match s.as_bytes()[0] {
85
0
            b'-' => (true, &s[1..]),
86
0
            b'+' => (false, &s[1..]),
87
0
            _ => (false, s),
88
        };
89
90
        // Trim leading 0s
91
0
        let s = s.trim_start_matches('0');
92
0
        if s.is_empty() {
93
0
            return Ok(i256::ZERO);
94
0
        }
95
96
0
        if !s.as_bytes()[0].is_ascii_digit() {
97
            // Ensures no duplicate sign
98
0
            return Err(ParseI256Error {});
99
0
        }
100
101
0
        parse_impl(s, negative)
102
0
    }
103
}
104
105
impl From<i8> for i256 {
106
0
    fn from(value: i8) -> Self {
107
0
        Self::from_i128(value.into())
108
0
    }
109
}
110
111
impl From<i16> for i256 {
112
0
    fn from(value: i16) -> Self {
113
0
        Self::from_i128(value.into())
114
0
    }
115
}
116
117
impl From<i32> for i256 {
118
0
    fn from(value: i32) -> Self {
119
0
        Self::from_i128(value.into())
120
0
    }
121
}
122
123
impl From<i64> for i256 {
124
0
    fn from(value: i64) -> Self {
125
0
        Self::from_i128(value.into())
126
0
    }
127
}
128
129
/// Parse `s` with any sign and leading 0s removed
130
0
fn parse_impl(s: &str, negative: bool) -> Result<i256, ParseI256Error> {
131
0
    if s.len() <= 38 {
132
0
        let low = i128::from_str(s)?;
133
0
        return Ok(match negative {
134
0
            true => i256::from_parts(low.neg() as _, -1),
135
0
            false => i256::from_parts(low as _, 0),
136
        });
137
0
    }
138
139
0
    let split = s.len() - 38;
140
0
    if !s.as_bytes()[split].is_ascii_digit() {
141
        // Ensures not splitting codepoint and no sign
142
0
        return Err(ParseI256Error {});
143
0
    }
144
0
    let (hs, ls) = s.split_at(split);
145
146
0
    let mut low = i128::from_str(ls)?;
147
0
    let high = parse_impl(hs, negative)?;
148
149
0
    if negative {
150
0
        low = -low;
151
0
    }
152
153
0
    let low = i256::from_i128(low);
154
155
0
    high.checked_mul(i256::from_i128(10_i128.pow(38)))
156
0
        .and_then(|high| high.checked_add(low))
157
0
        .ok_or(ParseI256Error {})
158
0
}
159
160
impl PartialOrd for i256 {
161
0
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
162
0
        Some(self.cmp(other))
163
0
    }
164
}
165
166
impl Ord for i256 {
167
0
    fn cmp(&self, other: &Self) -> Ordering {
168
        // This is 25x faster than using a variable length encoding such
169
        // as BigInt as it avoids allocation and branching
170
0
        self.high.cmp(&other.high).then(self.low.cmp(&other.low))
171
0
    }
172
}
173
174
impl i256 {
175
    /// The additive identity for this integer type, i.e. `0`.
176
    pub const ZERO: Self = i256 { low: 0, high: 0 };
177
178
    /// The multiplicative identity for this integer type, i.e. `1`.
179
    pub const ONE: Self = i256 { low: 1, high: 0 };
180
181
    /// The multiplicative inverse for this integer type, i.e. `-1`.
182
    pub const MINUS_ONE: Self = i256 {
183
        low: u128::MAX,
184
        high: -1,
185
    };
186
187
    /// The maximum value that can be represented by this integer type
188
    pub const MAX: Self = i256 {
189
        low: u128::MAX,
190
        high: i128::MAX,
191
    };
192
193
    /// The minimum value that can be represented by this integer type
194
    pub const MIN: Self = i256 {
195
        low: u128::MIN,
196
        high: i128::MIN,
197
    };
198
199
    /// Create an integer value from its representation as a byte array in little-endian.
200
    #[inline]
201
0
    pub const fn from_le_bytes(b: [u8; 32]) -> Self {
202
0
        let (low, high) = split_array(b);
203
0
        Self {
204
0
            high: i128::from_le_bytes(high),
205
0
            low: u128::from_le_bytes(low),
206
0
        }
207
0
    }
208
209
    /// Create an integer value from its representation as a byte array in big-endian.
210
    #[inline]
211
    pub const fn from_be_bytes(b: [u8; 32]) -> Self {
212
        let (high, low) = split_array(b);
213
        Self {
214
            high: i128::from_be_bytes(high),
215
            low: u128::from_be_bytes(low),
216
        }
217
    }
218
219
    /// Create an `i256` value from a 128-bit value.
220
0
    pub const fn from_i128(v: i128) -> Self {
221
0
        Self::from_parts(v as u128, v >> 127)
222
0
    }
223
224
    /// Create an integer value from its representation as string.
225
    #[inline]
226
    pub fn from_string(value_str: &str) -> Option<Self> {
227
        value_str.parse().ok()
228
    }
229
230
    /// Create an optional i256 from the provided `f64`. Returning `None`
231
    /// if overflow occurred
232
0
    pub fn from_f64(v: f64) -> Option<Self> {
233
0
        BigInt::from_f64(v).and_then(|i| {
234
0
            let (integer, overflow) = i256::from_bigint_with_overflow(i);
235
0
            if overflow { None } else { Some(integer) }
236
0
        })
237
0
    }
238
239
    /// Create an i256 from the provided low u128 and high i128
240
    #[inline]
241
0
    pub const fn from_parts(low: u128, high: i128) -> Self {
242
0
        Self { low, high }
243
0
    }
244
245
    /// Returns this `i256` as a low u128 and high i128
246
0
    pub const fn to_parts(self) -> (u128, i128) {
247
0
        (self.low, self.high)
248
0
    }
249
250
    /// Converts this `i256` into an `i128` returning `None` if this would result
251
    /// in truncation/overflow
252
0
    pub fn to_i128(self) -> Option<i128> {
253
0
        let as_i128 = self.low as i128;
254
255
0
        let high_negative = self.high < 0;
256
0
        let low_negative = as_i128 < 0;
257
0
        let high_valid = self.high == -1 || self.high == 0;
258
259
0
        (high_negative == low_negative && high_valid).then_some(self.low as i128)
260
0
    }
261
262
    /// Wraps this `i256` into an `i128`
263
0
    pub fn as_i128(self) -> i128 {
264
0
        self.low as i128
265
0
    }
266
267
    /// Return the memory representation of this integer as a byte array in little-endian byte order.
268
    #[inline]
269
0
    pub const fn to_le_bytes(self) -> [u8; 32] {
270
0
        let low = self.low.to_le_bytes();
271
0
        let high = self.high.to_le_bytes();
272
0
        let mut t = [0; 32];
273
0
        let mut i = 0;
274
0
        while i != 16 {
275
0
            t[i] = low[i];
276
0
            t[i + 16] = high[i];
277
0
            i += 1;
278
0
        }
279
0
        t
280
0
    }
281
282
    /// Return the memory representation of this integer as a byte array in big-endian byte order.
283
    #[inline]
284
    pub const fn to_be_bytes(self) -> [u8; 32] {
285
        let low = self.low.to_be_bytes();
286
        let high = self.high.to_be_bytes();
287
        let mut t = [0; 32];
288
        let mut i = 0;
289
        while i != 16 {
290
            t[i] = high[i];
291
            t[i + 16] = low[i];
292
            i += 1;
293
        }
294
        t
295
    }
296
297
    /// Create an i256 from the provided [`BigInt`] returning a bool indicating
298
    /// if overflow occurred
299
0
    fn from_bigint_with_overflow(v: BigInt) -> (Self, bool) {
300
0
        let v_bytes = v.to_signed_bytes_le();
301
0
        match v_bytes.len().cmp(&32) {
302
            Ordering::Less => {
303
0
                let mut bytes = if num_traits::Signed::is_negative(&v) {
304
0
                    [255_u8; 32]
305
                } else {
306
0
                    [0; 32]
307
                };
308
0
                bytes[0..v_bytes.len()].copy_from_slice(&v_bytes[..v_bytes.len()]);
309
0
                (Self::from_le_bytes(bytes), false)
310
            }
311
0
            Ordering::Equal => (Self::from_le_bytes(v_bytes.try_into().unwrap()), false),
312
0
            Ordering::Greater => (Self::from_le_bytes(v_bytes[..32].try_into().unwrap()), true),
313
        }
314
0
    }
315
316
    /// Computes the absolute value of this i256
317
    #[inline]
318
0
    pub fn wrapping_abs(self) -> Self {
319
        // -1 if negative, otherwise 0
320
0
        let sa = self.high >> 127;
321
0
        let sa = Self::from_parts(sa as u128, sa);
322
323
        // Inverted if negative
324
0
        Self::from_parts(self.low ^ sa.low, self.high ^ sa.high).wrapping_sub(sa)
325
0
    }
326
327
    /// Computes the absolute value of this i256 returning `None` if `Self == Self::MIN`
328
    #[inline]
329
    pub fn checked_abs(self) -> Option<Self> {
330
        (self != Self::MIN).then(|| self.wrapping_abs())
331
    }
332
333
    /// Negates this i256
334
    #[inline]
335
0
    pub fn wrapping_neg(self) -> Self {
336
0
        Self::from_parts(!self.low, !self.high).wrapping_add(i256::ONE)
337
0
    }
338
339
    /// Negates this i256 returning `None` if `Self == Self::MIN`
340
    #[inline]
341
0
    pub fn checked_neg(self) -> Option<Self> {
342
0
        (self != Self::MIN).then(|| self.wrapping_neg())
343
0
    }
344
345
    /// Performs wrapping addition
346
    #[inline]
347
0
    pub fn wrapping_add(self, other: Self) -> Self {
348
0
        let (low, carry) = self.low.overflowing_add(other.low);
349
0
        let high = self.high.wrapping_add(other.high).wrapping_add(carry as _);
350
0
        Self { low, high }
351
0
    }
352
353
    /// Performs checked addition
354
    #[inline]
355
0
    pub fn checked_add(self, other: Self) -> Option<Self> {
356
0
        let r = self.wrapping_add(other);
357
0
        ((other.is_negative() && r < self) || (!other.is_negative() && r >= self)).then_some(r)
358
0
    }
359
360
    /// Performs wrapping subtraction
361
    #[inline]
362
0
    pub fn wrapping_sub(self, other: Self) -> Self {
363
0
        let (low, carry) = self.low.overflowing_sub(other.low);
364
0
        let high = self.high.wrapping_sub(other.high).wrapping_sub(carry as _);
365
0
        Self { low, high }
366
0
    }
367
368
    /// Performs checked subtraction
369
    #[inline]
370
0
    pub fn checked_sub(self, other: Self) -> Option<Self> {
371
0
        let r = self.wrapping_sub(other);
372
0
        ((other.is_negative() && r > self) || (!other.is_negative() && r <= self)).then_some(r)
373
0
    }
374
375
    /// Performs wrapping multiplication
376
    #[inline]
377
    pub fn wrapping_mul(self, other: Self) -> Self {
378
        let (low, high) = mulx(self.low, other.low);
379
380
        // Compute the high multiples, only impacting the high 128-bits
381
        let hl = self.high.wrapping_mul(other.low as i128);
382
        let lh = (self.low as i128).wrapping_mul(other.high);
383
384
        Self {
385
            low,
386
            high: (high as i128).wrapping_add(hl).wrapping_add(lh),
387
        }
388
    }
389
390
    /// Performs checked multiplication
391
    #[inline]
392
0
    pub fn checked_mul(self, other: Self) -> Option<Self> {
393
0
        if self == i256::ZERO || other == i256::ZERO {
394
0
            return Some(i256::ZERO);
395
0
        }
396
397
        // Shift sign bit down to construct mask of all set bits if negative
398
0
        let l_sa = self.high >> 127;
399
0
        let r_sa = other.high >> 127;
400
0
        let out_sa = (l_sa ^ r_sa) as u128;
401
402
        // Compute absolute values
403
0
        let l_abs = self.wrapping_abs();
404
0
        let r_abs = other.wrapping_abs();
405
406
        // Overflow if both high parts are non-zero
407
0
        if l_abs.high != 0 && r_abs.high != 0 {
408
0
            return None;
409
0
        }
410
411
        // Perform checked multiplication on absolute values
412
0
        let (low, high) = mulx(l_abs.low, r_abs.low);
413
414
        // Compute the high multiples, only impacting the high 128-bits
415
0
        let hl = (l_abs.high as u128).checked_mul(r_abs.low)?;
416
0
        let lh = l_abs.low.checked_mul(r_abs.high as u128)?;
417
418
0
        let high = high.checked_add(hl)?.checked_add(lh)?;
419
420
        // Reverse absolute value, if necessary
421
0
        let (low, c) = (low ^ out_sa).overflowing_sub(out_sa);
422
0
        let high = (high ^ out_sa).wrapping_sub(out_sa).wrapping_sub(c as u128) as i128;
423
424
        // Check for overflow in final conversion
425
0
        (high.is_negative() == (self.is_negative() ^ other.is_negative()))
426
0
            .then_some(Self { low, high })
427
0
    }
428
429
    /// Division operation, returns (quotient, remainder).
430
    /// This basically implements [Long division]: `<https://en.wikipedia.org/wiki/Division_algorithm>`
431
    #[inline]
432
0
    fn div_rem(self, other: Self) -> Result<(Self, Self), DivRemError> {
433
0
        if other == Self::ZERO {
434
0
            return Err(DivRemError::DivideByZero);
435
0
        }
436
0
        if other == Self::MINUS_ONE && self == Self::MIN {
437
0
            return Err(DivRemError::DivideOverflow);
438
0
        }
439
440
0
        let a = self.wrapping_abs();
441
0
        let b = other.wrapping_abs();
442
443
0
        let (div, rem) = div_rem(&a.as_digits(), &b.as_digits());
444
0
        let div = Self::from_digits(div);
445
0
        let rem = Self::from_digits(rem);
446
447
        Ok((
448
0
            if self.is_negative() == other.is_negative() {
449
0
                div
450
            } else {
451
0
                div.wrapping_neg()
452
            },
453
0
            if self.is_negative() {
454
0
                rem.wrapping_neg()
455
            } else {
456
0
                rem
457
            },
458
        ))
459
0
    }
460
461
    /// Interpret this [`i256`] as 4 `u64` digits, least significant first
462
0
    fn as_digits(self) -> [u64; 4] {
463
0
        [
464
0
            self.low as u64,
465
0
            (self.low >> 64) as u64,
466
0
            self.high as u64,
467
0
            (self.high as u128 >> 64) as u64,
468
0
        ]
469
0
    }
470
471
    /// Interpret 4 `u64` digits, least significant first, as a [`i256`]
472
0
    fn from_digits(digits: [u64; 4]) -> Self {
473
0
        Self::from_parts(
474
0
            digits[0] as u128 | ((digits[1] as u128) << 64),
475
0
            digits[2] as i128 | ((digits[3] as i128) << 64),
476
        )
477
0
    }
478
479
    /// Performs wrapping division
480
    #[inline]
481
    pub fn wrapping_div(self, other: Self) -> Self {
482
        match self.div_rem(other) {
483
            Ok((v, _)) => v,
484
            Err(DivRemError::DivideByZero) => panic!("attempt to divide by zero"),
485
            Err(_) => Self::MIN,
486
        }
487
    }
488
489
    /// Performs checked division
490
    #[inline]
491
0
    pub fn checked_div(self, other: Self) -> Option<Self> {
492
0
        self.div_rem(other).map(|(v, _)| v).ok()
493
0
    }
494
495
    /// Performs wrapping remainder
496
    #[inline]
497
    pub fn wrapping_rem(self, other: Self) -> Self {
498
        match self.div_rem(other) {
499
            Ok((_, v)) => v,
500
            Err(DivRemError::DivideByZero) => panic!("attempt to divide by zero"),
501
            Err(_) => Self::ZERO,
502
        }
503
    }
504
505
    /// Performs checked remainder
506
    #[inline]
507
0
    pub fn checked_rem(self, other: Self) -> Option<Self> {
508
0
        self.div_rem(other).map(|(_, v)| v).ok()
509
0
    }
510
511
    /// Performs checked exponentiation
512
    #[inline]
513
    pub fn checked_pow(self, mut exp: u32) -> Option<Self> {
514
        if exp == 0 {
515
            return Some(i256::from_i128(1));
516
        }
517
518
        let mut base = self;
519
        let mut acc: Self = i256::from_i128(1);
520
521
        while exp > 1 {
522
            if (exp & 1) == 1 {
523
                acc = acc.checked_mul(base)?;
524
            }
525
            exp /= 2;
526
            base = base.checked_mul(base)?;
527
        }
528
        // since exp!=0, finally the exp must be 1.
529
        // Deal with the final bit of the exponent separately, since
530
        // squaring the base afterwards is not necessary and may cause a
531
        // needless overflow.
532
        acc.checked_mul(base)
533
    }
534
535
    /// Performs wrapping exponentiation
536
    #[inline]
537
    pub fn wrapping_pow(self, mut exp: u32) -> Self {
538
        if exp == 0 {
539
            return i256::from_i128(1);
540
        }
541
542
        let mut base = self;
543
        let mut acc: Self = i256::from_i128(1);
544
545
        while exp > 1 {
546
            if (exp & 1) == 1 {
547
                acc = acc.wrapping_mul(base);
548
            }
549
            exp /= 2;
550
            base = base.wrapping_mul(base);
551
        }
552
553
        // since exp!=0, finally the exp must be 1.
554
        // Deal with the final bit of the exponent separately, since
555
        // squaring the base afterwards is not necessary and may cause a
556
        // needless overflow.
557
        acc.wrapping_mul(base)
558
    }
559
560
    /// Returns a number [`i256`] representing sign of this [`i256`].
561
    ///
562
    /// 0 if the number is zero
563
    /// 1 if the number is positive
564
    /// -1 if the number is negative
565
0
    pub const fn signum(self) -> Self {
566
0
        if self.is_positive() {
567
0
            i256::ONE
568
0
        } else if self.is_negative() {
569
0
            i256::MINUS_ONE
570
        } else {
571
0
            i256::ZERO
572
        }
573
0
    }
574
575
    /// Returns `true` if this [`i256`] is negative
576
    #[inline]
577
0
    pub const fn is_negative(self) -> bool {
578
0
        self.high.is_negative()
579
0
    }
580
581
    /// Returns `true` if this [`i256`] is positive
582
0
    pub const fn is_positive(self) -> bool {
583
0
        self.high.is_positive() || self.high == 0 && self.low != 0
584
0
    }
585
586
0
    fn leading_zeros(&self) -> u32 {
587
0
        match self.high {
588
0
            0 => u128::BITS + self.low.leading_zeros(),
589
0
            _ => self.high.leading_zeros(),
590
        }
591
0
    }
592
593
0
    fn redundant_leading_sign_bits_i256(n: i256) -> u8 {
594
0
        let mask = n >> 255; // all ones or all zeros
595
0
        ((n ^ mask).leading_zeros() - 1) as u8 // we only need one sign bit
596
0
    }
597
598
0
    fn i256_to_f64(input: i256) -> f64 {
599
0
        let k = i256::redundant_leading_sign_bits_i256(input);
600
0
        let n = input << k; // left-justify (no redundant sign bits)
601
0
        let n = (n.high >> 64) as i64; // throw away the lower 192 bits
602
0
        (n as f64) * f64::powi(2.0, 192 - (k as i32)) // convert to f64 and scale it, as we left-shift k bit previous, so we need to scale it by 2^(192-k)
603
0
    }
604
}
605
606
/// Temporary workaround due to lack of stable const array slicing
607
/// See <https://github.com/rust-lang/rust/issues/90091>
608
0
const fn split_array<const N: usize, const M: usize>(vals: [u8; N]) -> ([u8; M], [u8; M]) {
609
0
    let mut a = [0; M];
610
0
    let mut b = [0; M];
611
0
    let mut i = 0;
612
0
    while i != M {
613
0
        a[i] = vals[i];
614
0
        b[i] = vals[i + M];
615
0
        i += 1;
616
0
    }
617
0
    (a, b)
618
0
}
619
620
/// Performs an unsigned multiplication of `a * b` returning a tuple of
621
/// `(low, high)` where `low` contains the lower 128-bits of the result
622
/// and `high` the higher 128-bits
623
///
624
/// This mirrors the x86 mulx instruction but for 128-bit types
625
#[inline]
626
0
fn mulx(a: u128, b: u128) -> (u128, u128) {
627
0
    let split = |a: u128| (a & (u64::MAX as u128), a >> 64);
628
629
    const MASK: u128 = u64::MAX as _;
630
631
0
    let (a_low, a_high) = split(a);
632
0
    let (b_low, b_high) = split(b);
633
634
    // Carry stores the upper 64-bits of low and lower 64-bits of high
635
0
    let (mut low, mut carry) = split(a_low * b_low);
636
0
    carry += a_high * b_low;
637
638
    // Update low and high with corresponding parts of carry
639
0
    low += carry << 64;
640
0
    let mut high = carry >> 64;
641
642
    // Update carry with overflow from low
643
0
    carry = low >> 64;
644
0
    low &= MASK;
645
646
    // Perform multiply including overflow from low
647
0
    carry += b_high * a_low;
648
649
    // Update low and high with values from carry
650
0
    low += carry << 64;
651
0
    high += carry >> 64;
652
653
    // Perform 4th multiplication
654
0
    high += a_high * b_high;
655
656
0
    (low, high)
657
0
}
658
659
derive_arith!(
660
    i256,
661
    Add,
662
    AddAssign,
663
    add,
664
    add_assign,
665
    wrapping_add,
666
    checked_add
667
);
668
derive_arith!(
669
    i256,
670
    Sub,
671
    SubAssign,
672
    sub,
673
    sub_assign,
674
    wrapping_sub,
675
    checked_sub
676
);
677
derive_arith!(
678
    i256,
679
    Mul,
680
    MulAssign,
681
    mul,
682
    mul_assign,
683
    wrapping_mul,
684
    checked_mul
685
);
686
derive_arith!(
687
    i256,
688
    Div,
689
    DivAssign,
690
    div,
691
    div_assign,
692
    wrapping_div,
693
    checked_div
694
);
695
derive_arith!(
696
    i256,
697
    Rem,
698
    RemAssign,
699
    rem,
700
    rem_assign,
701
    wrapping_rem,
702
    checked_rem
703
);
704
705
impl Neg for i256 {
706
    type Output = i256;
707
708
    #[cfg(debug_assertions)]
709
0
    fn neg(self) -> Self::Output {
710
0
        self.checked_neg().expect("i256 overflow")
711
0
    }
712
713
    #[cfg(not(debug_assertions))]
714
    fn neg(self) -> Self::Output {
715
        self.wrapping_neg()
716
    }
717
}
718
719
impl BitAnd for i256 {
720
    type Output = i256;
721
722
    #[inline]
723
    fn bitand(self, rhs: Self) -> Self::Output {
724
        Self {
725
            low: self.low & rhs.low,
726
            high: self.high & rhs.high,
727
        }
728
    }
729
}
730
731
impl BitOr for i256 {
732
    type Output = i256;
733
734
    #[inline]
735
    fn bitor(self, rhs: Self) -> Self::Output {
736
        Self {
737
            low: self.low | rhs.low,
738
            high: self.high | rhs.high,
739
        }
740
    }
741
}
742
743
impl BitXor for i256 {
744
    type Output = i256;
745
746
    #[inline]
747
0
    fn bitxor(self, rhs: Self) -> Self::Output {
748
0
        Self {
749
0
            low: self.low ^ rhs.low,
750
0
            high: self.high ^ rhs.high,
751
0
        }
752
0
    }
753
}
754
755
impl Shl<u8> for i256 {
756
    type Output = i256;
757
758
    #[inline]
759
0
    fn shl(self, rhs: u8) -> Self::Output {
760
0
        if rhs == 0 {
761
0
            self
762
0
        } else if rhs < 128 {
763
0
            Self {
764
0
                high: (self.high << rhs) | (self.low >> (128 - rhs)) as i128,
765
0
                low: self.low << rhs,
766
0
            }
767
        } else {
768
0
            Self {
769
0
                high: (self.low << (rhs - 128)) as i128,
770
0
                low: 0,
771
0
            }
772
        }
773
0
    }
774
}
775
776
impl Shr<u8> for i256 {
777
    type Output = i256;
778
779
    #[inline]
780
0
    fn shr(self, rhs: u8) -> Self::Output {
781
0
        if rhs == 0 {
782
0
            self
783
0
        } else if rhs < 128 {
784
0
            Self {
785
0
                high: self.high >> rhs,
786
0
                low: (self.low >> rhs) | ((self.high as u128) << (128 - rhs)),
787
0
            }
788
        } else {
789
0
            Self {
790
0
                high: self.high >> 127,
791
0
                low: (self.high >> (rhs - 128)) as u128,
792
0
            }
793
        }
794
0
    }
795
}
796
797
macro_rules! define_as_primitive {
798
    ($native_ty:ty) => {
799
        impl AsPrimitive<i256> for $native_ty {
800
0
            fn as_(self) -> i256 {
801
0
                i256::from_i128(self as i128)
802
0
            }
803
        }
804
    };
805
}
806
807
define_as_primitive!(i8);
808
define_as_primitive!(i16);
809
define_as_primitive!(i32);
810
define_as_primitive!(i64);
811
define_as_primitive!(u8);
812
define_as_primitive!(u16);
813
define_as_primitive!(u32);
814
define_as_primitive!(u64);
815
816
impl ToPrimitive for i256 {
817
0
    fn to_i64(&self) -> Option<i64> {
818
0
        let as_i128 = self.low as i128;
819
820
0
        let high_negative = self.high < 0;
821
0
        let low_negative = as_i128 < 0;
822
0
        let high_valid = self.high == -1 || self.high == 0;
823
824
0
        if high_negative == low_negative && high_valid {
825
0
            let (low_bytes, high_bytes) = split_array(u128::to_le_bytes(self.low));
826
0
            let high = i64::from_le_bytes(high_bytes);
827
0
            let low = i64::from_le_bytes(low_bytes);
828
829
0
            let high_negative = high < 0;
830
0
            let low_negative = low < 0;
831
0
            let high_valid = self.high == -1 || self.high == 0;
832
833
0
            (high_negative == low_negative && high_valid).then_some(low)
834
        } else {
835
0
            None
836
        }
837
0
    }
838
839
0
    fn to_f64(&self) -> Option<f64> {
840
0
        match *self {
841
0
            Self::MIN => Some(-2_f64.powi(255)),
842
0
            Self::ZERO => Some(0f64),
843
0
            Self::ONE => Some(1f64),
844
0
            n => Some(Self::i256_to_f64(n)),
845
        }
846
0
    }
847
848
0
    fn to_u64(&self) -> Option<u64> {
849
0
        let as_i128 = self.low as i128;
850
851
0
        let high_negative = self.high < 0;
852
0
        let low_negative = as_i128 < 0;
853
0
        let high_valid = self.high == -1 || self.high == 0;
854
855
0
        if high_negative == low_negative && high_valid {
856
0
            self.low.to_u64()
857
        } else {
858
0
            None
859
        }
860
0
    }
861
}
862
863
#[cfg(all(test, not(miri)))] // llvm.x86.subborrow.64 not supported by MIRI
864
mod tests {
865
    use super::*;
866
    use num_traits::Signed;
867
    use rand::{Rng, rng};
868
869
    #[test]
870
    fn test_signed_cmp() {
871
        let a = i256::from_parts(i128::MAX as u128, 12);
872
        let b = i256::from_parts(i128::MIN as u128, 12);
873
        assert!(a < b);
874
875
        let a = i256::from_parts(i128::MAX as u128, 12);
876
        let b = i256::from_parts(i128::MIN as u128, -12);
877
        assert!(a > b);
878
    }
879
880
    #[test]
881
    fn test_to_i128() {
882
        let vals = [
883
            BigInt::from_i128(-1).unwrap(),
884
            BigInt::from_i128(i128::MAX).unwrap(),
885
            BigInt::from_i128(i128::MIN).unwrap(),
886
            BigInt::from_u128(u128::MIN).unwrap(),
887
            BigInt::from_u128(u128::MAX).unwrap(),
888
        ];
889
890
        for v in vals {
891
            let (t, overflow) = i256::from_bigint_with_overflow(v.clone());
892
            assert!(!overflow);
893
            assert_eq!(t.to_i128(), v.to_i128(), "{v} vs {t}");
894
        }
895
    }
896
897
    /// Tests operations against the two provided [`i256`]
898
    fn test_ops(il: i256, ir: i256) {
899
        let bl = BigInt::from_signed_bytes_le(&il.to_le_bytes());
900
        let br = BigInt::from_signed_bytes_le(&ir.to_le_bytes());
901
902
        // Comparison
903
        assert_eq!(il.cmp(&ir), bl.cmp(&br), "{bl} cmp {br}");
904
905
        // Conversions
906
        assert_eq!(i256::from_le_bytes(il.to_le_bytes()), il);
907
        assert_eq!(i256::from_be_bytes(il.to_be_bytes()), il);
908
        assert_eq!(i256::from_le_bytes(ir.to_le_bytes()), ir);
909
        assert_eq!(i256::from_be_bytes(ir.to_be_bytes()), ir);
910
911
        // To i128
912
        assert_eq!(il.to_i128(), bl.to_i128(), "{bl}");
913
        assert_eq!(ir.to_i128(), br.to_i128(), "{br}");
914
915
        // Absolute value
916
        let (abs, overflow) = i256::from_bigint_with_overflow(bl.abs());
917
        assert_eq!(il.wrapping_abs(), abs);
918
        assert_eq!(il.checked_abs().is_none(), overflow);
919
920
        let (abs, overflow) = i256::from_bigint_with_overflow(br.abs());
921
        assert_eq!(ir.wrapping_abs(), abs);
922
        assert_eq!(ir.checked_abs().is_none(), overflow);
923
924
        // Negation
925
        let (neg, overflow) = i256::from_bigint_with_overflow(bl.clone().neg());
926
        assert_eq!(il.wrapping_neg(), neg);
927
        assert_eq!(il.checked_neg().is_none(), overflow);
928
929
        // Negation
930
        let (neg, overflow) = i256::from_bigint_with_overflow(br.clone().neg());
931
        assert_eq!(ir.wrapping_neg(), neg);
932
        assert_eq!(ir.checked_neg().is_none(), overflow);
933
934
        // Addition
935
        let actual = il.wrapping_add(ir);
936
        let (expected, overflow) = i256::from_bigint_with_overflow(bl.clone() + br.clone());
937
        assert_eq!(actual, expected);
938
939
        let checked = il.checked_add(ir);
940
        match overflow {
941
            true => assert!(checked.is_none()),
942
            false => assert_eq!(checked, Some(actual)),
943
        }
944
945
        // Subtraction
946
        let actual = il.wrapping_sub(ir);
947
        let (expected, overflow) = i256::from_bigint_with_overflow(bl.clone() - br.clone());
948
        assert_eq!(actual.to_string(), expected.to_string());
949
950
        let checked = il.checked_sub(ir);
951
        match overflow {
952
            true => assert!(checked.is_none()),
953
            false => assert_eq!(checked, Some(actual), "{bl} - {br} = {expected}"),
954
        }
955
956
        // Multiplication
957
        let actual = il.wrapping_mul(ir);
958
        let (expected, overflow) = i256::from_bigint_with_overflow(bl.clone() * br.clone());
959
        assert_eq!(actual.to_string(), expected.to_string());
960
961
        let checked = il.checked_mul(ir);
962
        match overflow {
963
            true => assert!(
964
                checked.is_none(),
965
                "{il} * {ir} = {actual} vs {bl} * {br} = {expected}"
966
            ),
967
            false => assert_eq!(
968
                checked,
969
                Some(actual),
970
                "{il} * {ir} = {actual} vs {bl} * {br} = {expected}"
971
            ),
972
        }
973
974
        // Division
975
        if ir != i256::ZERO {
976
            let actual = il.wrapping_div(ir);
977
            let expected = bl.clone() / br.clone();
978
            let checked = il.checked_div(ir);
979
980
            if ir == i256::MINUS_ONE && il == i256::MIN {
981
                // BigInt produces an integer over i256::MAX
982
                assert_eq!(actual, i256::MIN);
983
                assert!(checked.is_none());
984
            } else {
985
                assert_eq!(actual.to_string(), expected.to_string());
986
                assert_eq!(checked.unwrap().to_string(), expected.to_string());
987
            }
988
        } else {
989
            // `wrapping_div` panics on division by zero
990
            assert!(il.checked_div(ir).is_none());
991
        }
992
993
        // Remainder
994
        if ir != i256::ZERO {
995
            let actual = il.wrapping_rem(ir);
996
            let expected = bl.clone() % br.clone();
997
            let checked = il.checked_rem(ir);
998
999
            assert_eq!(actual.to_string(), expected.to_string(), "{il} % {ir}");
1000
1001
            if ir == i256::MINUS_ONE && il == i256::MIN {
1002
                assert!(checked.is_none());
1003
            } else {
1004
                assert_eq!(checked.unwrap().to_string(), expected.to_string());
1005
            }
1006
        } else {
1007
            // `wrapping_rem` panics on division by zero
1008
            assert!(il.checked_rem(ir).is_none());
1009
        }
1010
1011
        // Exponentiation
1012
        for exp in vec![0, 1, 2, 3, 8, 100].into_iter() {
1013
            let actual = il.wrapping_pow(exp);
1014
            let (expected, overflow) = i256::from_bigint_with_overflow(bl.clone().pow(exp));
1015
            assert_eq!(actual.to_string(), expected.to_string());
1016
1017
            let checked = il.checked_pow(exp);
1018
            match overflow {
1019
                true => assert!(
1020
                    checked.is_none(),
1021
                    "{il} ^ {exp} = {actual} vs {bl} * {exp} = {expected}"
1022
                ),
1023
                false => assert_eq!(
1024
                    checked,
1025
                    Some(actual),
1026
                    "{il} ^ {exp} = {actual} vs {bl} ^ {exp} = {expected}"
1027
                ),
1028
            }
1029
        }
1030
1031
        // Bit operations
1032
        let actual = il & ir;
1033
        let (expected, _) = i256::from_bigint_with_overflow(bl.clone() & br.clone());
1034
        assert_eq!(actual.to_string(), expected.to_string());
1035
1036
        let actual = il | ir;
1037
        let (expected, _) = i256::from_bigint_with_overflow(bl.clone() | br.clone());
1038
        assert_eq!(actual.to_string(), expected.to_string());
1039
1040
        let actual = il ^ ir;
1041
        let (expected, _) = i256::from_bigint_with_overflow(bl.clone() ^ br);
1042
        assert_eq!(actual.to_string(), expected.to_string());
1043
1044
        for shift in [0_u8, 1, 4, 126, 128, 129, 254, 255] {
1045
            let actual = il << shift;
1046
            let (expected, _) = i256::from_bigint_with_overflow(bl.clone() << shift);
1047
            assert_eq!(actual.to_string(), expected.to_string());
1048
1049
            let actual = il >> shift;
1050
            let (expected, _) = i256::from_bigint_with_overflow(bl.clone() >> shift);
1051
            assert_eq!(actual.to_string(), expected.to_string());
1052
        }
1053
    }
1054
1055
    #[test]
1056
    fn test_i256() {
1057
        let candidates = [
1058
            i256::ZERO,
1059
            i256::ONE,
1060
            i256::MINUS_ONE,
1061
            i256::from_i128(2),
1062
            i256::from_i128(-2),
1063
            i256::from_parts(u128::MAX, 1),
1064
            i256::from_parts(u128::MAX, -1),
1065
            i256::from_parts(0, 1),
1066
            i256::from_parts(0, -1),
1067
            i256::from_parts(1, -1),
1068
            i256::from_parts(1, 1),
1069
            i256::from_parts(0, i128::MAX),
1070
            i256::from_parts(0, i128::MIN),
1071
            i256::from_parts(1, i128::MAX),
1072
            i256::from_parts(1, i128::MIN),
1073
            i256::from_parts(u128::MAX, i128::MIN),
1074
            i256::from_parts(100, 32),
1075
            i256::MIN,
1076
            i256::MAX,
1077
            i256::MIN >> 1,
1078
            i256::MAX >> 1,
1079
            i256::ONE << 127,
1080
            i256::ONE << 128,
1081
            i256::ONE << 129,
1082
            i256::MINUS_ONE << 127,
1083
            i256::MINUS_ONE << 128,
1084
            i256::MINUS_ONE << 129,
1085
        ];
1086
1087
        for il in candidates {
1088
            for ir in candidates {
1089
                test_ops(il, ir)
1090
            }
1091
        }
1092
    }
1093
1094
    #[test]
1095
    fn test_signed_ops() {
1096
        // signum
1097
        assert_eq!(i256::from_i128(1).signum(), i256::ONE);
1098
        assert_eq!(i256::from_i128(0).signum(), i256::ZERO);
1099
        assert_eq!(i256::from_i128(-0).signum(), i256::ZERO);
1100
        assert_eq!(i256::from_i128(-1).signum(), i256::MINUS_ONE);
1101
1102
        // is_positive
1103
        assert!(i256::from_i128(1).is_positive());
1104
        assert!(!i256::from_i128(0).is_positive());
1105
        assert!(!i256::from_i128(-0).is_positive());
1106
        assert!(!i256::from_i128(-1).is_positive());
1107
1108
        // is_negative
1109
        assert!(!i256::from_i128(1).is_negative());
1110
        assert!(!i256::from_i128(0).is_negative());
1111
        assert!(!i256::from_i128(-0).is_negative());
1112
        assert!(i256::from_i128(-1).is_negative());
1113
    }
1114
1115
    #[test]
1116
    #[cfg_attr(miri, ignore)]
1117
    fn test_i256_fuzz() {
1118
        let mut rng = rng();
1119
1120
        for _ in 0..1000 {
1121
            let mut l = [0_u8; 32];
1122
            let len = rng.random_range(0..32);
1123
            l.iter_mut().take(len).for_each(|x| *x = rng.random());
1124
1125
            let mut r = [0_u8; 32];
1126
            let len = rng.random_range(0..32);
1127
            r.iter_mut().take(len).for_each(|x| *x = rng.random());
1128
1129
            test_ops(i256::from_le_bytes(l), i256::from_le_bytes(r))
1130
        }
1131
    }
1132
1133
    #[test]
1134
    fn test_i256_to_primitive() {
1135
        let a = i256::MAX;
1136
        assert!(a.to_i64().is_none());
1137
        assert!(a.to_u64().is_none());
1138
1139
        let a = i256::from_i128(i128::MAX);
1140
        assert!(a.to_i64().is_none());
1141
        assert!(a.to_u64().is_none());
1142
1143
        let a = i256::from_i128(i64::MAX as i128);
1144
        assert_eq!(a.to_i64().unwrap(), i64::MAX);
1145
        assert_eq!(a.to_u64().unwrap(), i64::MAX as u64);
1146
1147
        let a = i256::from_i128(i64::MAX as i128 + 1);
1148
        assert!(a.to_i64().is_none());
1149
        assert_eq!(a.to_u64().unwrap(), i64::MAX as u64 + 1);
1150
1151
        let a = i256::MIN;
1152
        assert!(a.to_i64().is_none());
1153
        assert!(a.to_u64().is_none());
1154
1155
        let a = i256::from_i128(i128::MIN);
1156
        assert!(a.to_i64().is_none());
1157
        assert!(a.to_u64().is_none());
1158
1159
        let a = i256::from_i128(i64::MIN as i128);
1160
        assert_eq!(a.to_i64().unwrap(), i64::MIN);
1161
        assert!(a.to_u64().is_none());
1162
1163
        let a = i256::from_i128(i64::MIN as i128 - 1);
1164
        assert!(a.to_i64().is_none());
1165
        assert!(a.to_u64().is_none());
1166
    }
1167
1168
    #[test]
1169
    fn test_i256_as_i128() {
1170
        let a = i256::from_i128(i128::MAX).wrapping_add(i256::from_i128(1));
1171
        let i128 = a.as_i128();
1172
        assert_eq!(i128, i128::MIN);
1173
1174
        let a = i256::from_i128(i128::MAX).wrapping_add(i256::from_i128(2));
1175
        let i128 = a.as_i128();
1176
        assert_eq!(i128, i128::MIN + 1);
1177
1178
        let a = i256::from_i128(i128::MIN).wrapping_sub(i256::from_i128(1));
1179
        let i128 = a.as_i128();
1180
        assert_eq!(i128, i128::MAX);
1181
1182
        let a = i256::from_i128(i128::MIN).wrapping_sub(i256::from_i128(2));
1183
        let i128 = a.as_i128();
1184
        assert_eq!(i128, i128::MAX - 1);
1185
    }
1186
1187
    #[test]
1188
    fn test_string_roundtrip() {
1189
        let roundtrip_cases = [
1190
            i256::ZERO,
1191
            i256::ONE,
1192
            i256::MINUS_ONE,
1193
            i256::from_i128(123456789),
1194
            i256::from_i128(-123456789),
1195
            i256::from_i128(i128::MIN),
1196
            i256::from_i128(i128::MAX),
1197
            i256::MIN,
1198
            i256::MAX,
1199
        ];
1200
        for case in roundtrip_cases {
1201
            let formatted = case.to_string();
1202
            let back: i256 = formatted.parse().unwrap();
1203
            assert_eq!(case, back);
1204
        }
1205
    }
1206
1207
    #[test]
1208
    fn test_from_string() {
1209
        let cases = [
1210
            (
1211
                "000000000000000000000000000000000000000011",
1212
                Some(i256::from_i128(11)),
1213
            ),
1214
            (
1215
                "-000000000000000000000000000000000000000011",
1216
                Some(i256::from_i128(-11)),
1217
            ),
1218
            (
1219
                "-0000000000000000000000000000000000000000123456789",
1220
                Some(i256::from_i128(-123456789)),
1221
            ),
1222
            ("-", None),
1223
            ("+", None),
1224
            ("--1", None),
1225
            ("-+1", None),
1226
            ("000000000000000000000000000000000000000", Some(i256::ZERO)),
1227
            ("0000000000000000000000000000000000000000-11", None),
1228
            ("11-1111111111111111111111111111111111111", None),
1229
            (
1230
                "115792089237316195423570985008687907853269984665640564039457584007913129639936",
1231
                None,
1232
            ),
1233
        ];
1234
        for (case, expected) in cases {
1235
            assert_eq!(i256::from_string(case), expected)
1236
        }
1237
    }
1238
1239
    #[allow(clippy::op_ref)]
1240
    fn test_reference_op(il: i256, ir: i256) {
1241
        let r1 = il + ir;
1242
        let r2 = &il + ir;
1243
        let r3 = il + &ir;
1244
        let r4 = &il + &ir;
1245
        assert_eq!(r1, r2);
1246
        assert_eq!(r1, r3);
1247
        assert_eq!(r1, r4);
1248
1249
        let r1 = il - ir;
1250
        let r2 = &il - ir;
1251
        let r3 = il - &ir;
1252
        let r4 = &il - &ir;
1253
        assert_eq!(r1, r2);
1254
        assert_eq!(r1, r3);
1255
        assert_eq!(r1, r4);
1256
1257
        let r1 = il * ir;
1258
        let r2 = &il * ir;
1259
        let r3 = il * &ir;
1260
        let r4 = &il * &ir;
1261
        assert_eq!(r1, r2);
1262
        assert_eq!(r1, r3);
1263
        assert_eq!(r1, r4);
1264
1265
        let r1 = il / ir;
1266
        let r2 = &il / ir;
1267
        let r3 = il / &ir;
1268
        let r4 = &il / &ir;
1269
        assert_eq!(r1, r2);
1270
        assert_eq!(r1, r3);
1271
        assert_eq!(r1, r4);
1272
    }
1273
1274
    #[test]
1275
    fn test_i256_reference_op() {
1276
        let candidates = [
1277
            i256::ONE,
1278
            i256::MINUS_ONE,
1279
            i256::from_i128(2),
1280
            i256::from_i128(-2),
1281
            i256::from_i128(3),
1282
            i256::from_i128(-3),
1283
        ];
1284
1285
        for il in candidates {
1286
            for ir in candidates {
1287
                test_reference_op(il, ir)
1288
            }
1289
        }
1290
    }
1291
1292
    #[test]
1293
    fn test_decimal256_to_f64_typical_values() {
1294
        let v = i256::from_i128(42_i128);
1295
        assert_eq!(v.to_f64().unwrap(), 42.0);
1296
1297
        let v = i256::from_i128(-123456789012345678i128);
1298
        assert_eq!(v.to_f64().unwrap(), -123456789012345678.0);
1299
1300
        let v = i256::from_string("0").unwrap();
1301
        assert_eq!(v.to_f64().unwrap(), 0.0);
1302
1303
        let v = i256::from_string("1").unwrap();
1304
        assert_eq!(v.to_f64().unwrap(), 1.0);
1305
1306
        let mut rng = rng();
1307
        for _ in 0..10 {
1308
            let f64_value =
1309
                (rng.random_range(i128::MIN..i128::MAX) as f64) * rng.random_range(0.0..1.0);
1310
            let big = i256::from_f64(f64_value).unwrap();
1311
            assert_eq!(big.to_f64().unwrap(), f64_value);
1312
        }
1313
    }
1314
1315
    #[test]
1316
    fn test_decimal256_to_f64_large_positive_value() {
1317
        let max_f = f64::MAX;
1318
        let big = i256::from_f64(max_f * 2.0).unwrap_or(i256::MAX);
1319
        let out = big.to_f64().unwrap();
1320
        assert!(out.is_finite() && out.is_sign_positive());
1321
    }
1322
1323
    #[test]
1324
    fn test_decimal256_to_f64_large_negative_value() {
1325
        let max_f = f64::MAX;
1326
        let big_neg = i256::from_f64(-(max_f * 2.0)).unwrap_or(i256::MIN);
1327
        let out = big_neg.to_f64().unwrap();
1328
        assert!(out.is_finite() && out.is_sign_negative());
1329
    }
1330
}