## 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
    }