use crate::bid_decimal_data::*;
use crate::bid_functions::*;
use crate::{BidUint64, BidUint128, BidUint256, IdecFlags, IdecRound};
pub const EXP_MAX_P1: u64 = 0x6000000000000000;
pub const EXP_P1: u64 = 0x0002000000000000;
pub const EXPMAX: i32 = 6111;
pub const EXPMIN: i32 = -6176;
pub const SIGNMASK32: u32 = 0x80000000;
pub const QUIET_MASK64: u64 = 0xfdffffffffffffff;
pub const P34: i32 = 34;
pub const DECIMAL_EXPONENT_BIAS_128: i32 = 6176;
pub const DECIMAL_MAX_EXPON_128: i32 = 12287;
pub const MAX_FORMAT_DIGITS_128: i32 = 34;
pub const _LARGEST_BID128_HIGH: u64 = 0x5fffed09bead87c0;
pub const _LARGEST_BID128_LOW: u64 = 0x378d8e63ffffffff;
pub const INFINITY_MASK64: u64 = 0x7800000000000000;
macro_rules! inc {
($x:expr, $y:expr) => {
$x = ($x).wrapping_add($y)
};
($x:expr) => {
$x = ($x).wrapping_add(1)
};
}
pub(crate) use inc;
macro_rules! dec {
($x:expr, $y:expr) => {
$x = ($x).wrapping_sub($y)
};
($x:expr) => {
$x = ($x).wrapping_sub(1)
};
}
pub(crate) use dec;
macro_rules! set_status_flags {
($fpsc:expr, $status:expr) => {
*$fpsc |= $status
};
}
pub(crate) use set_status_flags;
macro_rules! is_inexact {
($fpsc:expr) => {
*$fpsc & BID_INEXACT_EXCEPTION == BID_INEXACT_EXCEPTION
};
}
macro_rules! tolower_macro {
($x:expr) => {
if $x.is_ascii_uppercase() { $x - b'A' + b'a' } else { $x }
};
}
pub(crate) use tolower_macro;
macro_rules! bid_nr_digits {
($index:expr) => {
BID_NR_DIGITS[$index as usize]
};
}
pub(crate) use bid_nr_digits;
pub struct DecDigits {
pub digits: u32,
pub threshold_hi: u64,
pub threshold_lo: u64,
pub digits1: u32,
}
#[rustfmt::skip]
pub const BID_NR_DIGITS: [DecDigits; 113] = [
DecDigits{ digits: 1, threshold_hi: 0x0000000000000000, threshold_lo: 0x000000000000000a, digits1: 1 }, DecDigits{ digits: 1, threshold_hi: 0x0000000000000000, threshold_lo: 0x000000000000000a, digits1: 1 }, DecDigits{ digits: 1, threshold_hi: 0x0000000000000000, threshold_lo: 0x000000000000000a, digits1: 1 }, DecDigits{ digits: 0, threshold_hi: 0x0000000000000000, threshold_lo: 0x000000000000000a, digits1: 1 }, DecDigits{ digits: 2, threshold_hi: 0x0000000000000000, threshold_lo: 0x0000000000000064, digits1: 2 }, DecDigits{ digits: 2, threshold_hi: 0x0000000000000000, threshold_lo: 0x0000000000000064, digits1: 2 }, DecDigits{ digits: 0, threshold_hi: 0x0000000000000000, threshold_lo: 0x0000000000000064, digits1: 2 }, DecDigits{ digits: 3, threshold_hi: 0x0000000000000000, threshold_lo: 0x00000000000003e8, digits1: 3 }, DecDigits{ digits: 3, threshold_hi: 0x0000000000000000, threshold_lo: 0x00000000000003e8, digits1: 3 }, DecDigits{ digits: 0, threshold_hi: 0x0000000000000000, threshold_lo: 0x00000000000003e8, digits1: 3 }, DecDigits{ digits: 4, threshold_hi: 0x0000000000000000, threshold_lo: 0x0000000000002710, digits1: 4 }, DecDigits{ digits: 4, threshold_hi: 0x0000000000000000, threshold_lo: 0x0000000000002710, digits1: 4 }, DecDigits{ digits: 4, threshold_hi: 0x0000000000000000, threshold_lo: 0x0000000000002710, digits1: 4 }, DecDigits{ digits: 0, threshold_hi: 0x0000000000000000, threshold_lo: 0x0000000000002710, digits1: 4 }, DecDigits{ digits: 5, threshold_hi: 0x0000000000000000, threshold_lo: 0x00000000000186a0, digits1: 5 }, DecDigits{ digits: 5, threshold_hi: 0x0000000000000000, threshold_lo: 0x00000000000186a0, digits1: 5 }, DecDigits{ digits: 0, threshold_hi: 0x0000000000000000, threshold_lo: 0x00000000000186a0, digits1: 5 }, DecDigits{ digits: 6, threshold_hi: 0x0000000000000000, threshold_lo: 0x00000000000f4240, digits1: 6 }, DecDigits{ digits: 6, threshold_hi: 0x0000000000000000, threshold_lo: 0x00000000000f4240, digits1: 6 }, DecDigits{ digits: 0, threshold_hi: 0x0000000000000000, threshold_lo: 0x00000000000f4240, digits1: 6 }, DecDigits{ digits: 7, threshold_hi: 0x0000000000000000, threshold_lo: 0x0000000000989680, digits1: 7 }, DecDigits{ digits: 7, threshold_hi: 0x0000000000000000, threshold_lo: 0x0000000000989680, digits1: 7 }, DecDigits{ digits: 7, threshold_hi: 0x0000000000000000, threshold_lo: 0x0000000000989680, digits1: 7 }, DecDigits{ digits: 0, threshold_hi: 0x0000000000000000, threshold_lo: 0x0000000000989680, digits1: 7 }, DecDigits{ digits: 8, threshold_hi: 0x0000000000000000, threshold_lo: 0x0000000005f5e100, digits1: 8 }, DecDigits{ digits: 8, threshold_hi: 0x0000000000000000, threshold_lo: 0x0000000005f5e100, digits1: 8 }, DecDigits{ digits: 0, threshold_hi: 0x0000000000000000, threshold_lo: 0x0000000005f5e100, digits1: 8 }, DecDigits{ digits: 9, threshold_hi: 0x0000000000000000, threshold_lo: 0x000000003b9aca00, digits1: 9 }, DecDigits{ digits: 9, threshold_hi: 0x0000000000000000, threshold_lo: 0x000000003b9aca00, digits1: 9 }, DecDigits{ digits: 0, threshold_hi: 0x0000000000000000, threshold_lo: 0x000000003b9aca00, digits1: 9 }, DecDigits{ digits: 10, threshold_hi: 0x0000000000000000, threshold_lo: 0x00000002540be400, digits1: 10 }, DecDigits{ digits: 10, threshold_hi: 0x0000000000000000, threshold_lo: 0x00000002540be400, digits1: 10 }, DecDigits{ digits: 10, threshold_hi: 0x0000000000000000, threshold_lo: 0x00000002540be400, digits1: 10 }, DecDigits{ digits: 0, threshold_hi: 0x0000000000000000, threshold_lo: 0x00000002540be400, digits1: 10 }, DecDigits{ digits: 11, threshold_hi: 0x0000000000000000, threshold_lo: 0x000000174876e800, digits1: 11 }, DecDigits{ digits: 11, threshold_hi: 0x0000000000000000, threshold_lo: 0x000000174876e800, digits1: 11 }, DecDigits{ digits: 0, threshold_hi: 0x0000000000000000, threshold_lo: 0x000000174876e800, digits1: 11 }, DecDigits{ digits: 12, threshold_hi: 0x0000000000000000, threshold_lo: 0x000000e8d4a51000, digits1: 12 }, DecDigits{ digits: 12, threshold_hi: 0x0000000000000000, threshold_lo: 0x000000e8d4a51000, digits1: 12 }, DecDigits{ digits: 0, threshold_hi: 0x0000000000000000, threshold_lo: 0x000000e8d4a51000, digits1: 12 }, DecDigits{ digits: 13, threshold_hi: 0x0000000000000000, threshold_lo: 0x000009184e72a000, digits1: 13 }, DecDigits{ digits: 13, threshold_hi: 0x0000000000000000, threshold_lo: 0x000009184e72a000, digits1: 13 }, DecDigits{ digits: 13, threshold_hi: 0x0000000000000000, threshold_lo: 0x000009184e72a000, digits1: 13 }, DecDigits{ digits: 0, threshold_hi: 0x0000000000000000, threshold_lo: 0x000009184e72a000, digits1: 13 }, DecDigits{ digits: 14, threshold_hi: 0x0000000000000000, threshold_lo: 0x00005af3107a4000, digits1: 14 }, DecDigits{ digits: 14, threshold_hi: 0x0000000000000000, threshold_lo: 0x00005af3107a4000, digits1: 14 }, DecDigits{ digits: 0, threshold_hi: 0x0000000000000000, threshold_lo: 0x00005af3107a4000, digits1: 14 }, DecDigits{ digits: 15, threshold_hi: 0x0000000000000000, threshold_lo: 0x00038d7ea4c68000, digits1: 15 }, DecDigits{ digits: 15, threshold_hi: 0x0000000000000000, threshold_lo: 0x00038d7ea4c68000, digits1: 15 }, DecDigits{ digits: 0, threshold_hi: 0x0000000000000000, threshold_lo: 0x00038d7ea4c68000, digits1: 15 }, DecDigits{ digits: 16, threshold_hi: 0x0000000000000000, threshold_lo: 0x002386f26fc10000, digits1: 16 }, DecDigits{ digits: 16, threshold_hi: 0x0000000000000000, threshold_lo: 0x002386f26fc10000, digits1: 16 }, DecDigits{ digits: 16, threshold_hi: 0x0000000000000000, threshold_lo: 0x002386f26fc10000, digits1: 16 }, DecDigits{ digits: 0, threshold_hi: 0x0000000000000000, threshold_lo: 0x002386f26fc10000, digits1: 16 }, DecDigits{ digits: 17, threshold_hi: 0x0000000000000000, threshold_lo: 0x016345785d8a0000, digits1: 17 }, DecDigits{ digits: 17, threshold_hi: 0x0000000000000000, threshold_lo: 0x016345785d8a0000, digits1: 17 }, DecDigits{ digits: 0, threshold_hi: 0x0000000000000000, threshold_lo: 0x016345785d8a0000, digits1: 17 }, DecDigits{ digits: 18, threshold_hi: 0x0000000000000000, threshold_lo: 0x0de0b6b3a7640000, digits1: 18 }, DecDigits{ digits: 18, threshold_hi: 0x0000000000000000, threshold_lo: 0x0de0b6b3a7640000, digits1: 18 }, DecDigits{ digits: 0, threshold_hi: 0x0000000000000000, threshold_lo: 0x0de0b6b3a7640000, digits1: 18 }, DecDigits{ digits: 19, threshold_hi: 0x0000000000000000, threshold_lo: 0x8ac7230489e80000, digits1: 19 }, DecDigits{ digits: 19, threshold_hi: 0x0000000000000000, threshold_lo: 0x8ac7230489e80000, digits1: 19 }, DecDigits{ digits: 19, threshold_hi: 0x0000000000000000, threshold_lo: 0x8ac7230489e80000, digits1: 19 }, DecDigits{ digits: 0, threshold_hi: 0x0000000000000000, threshold_lo: 0x8ac7230489e80000, digits1: 19 }, DecDigits{ digits: 20, threshold_hi: 0x0000000000000005, threshold_lo: 0x6bc75e2d63100000, digits1: 20 }, DecDigits{ digits: 20, threshold_hi: 0x0000000000000005, threshold_lo: 0x6bc75e2d63100000, digits1: 20 }, DecDigits{ digits: 0, threshold_hi: 0x0000000000000005, threshold_lo: 0x6bc75e2d63100000, digits1: 20 }, DecDigits{ digits: 21, threshold_hi: 0x0000000000000036, threshold_lo: 0x35c9adc5dea00000, digits1: 21 }, DecDigits{ digits: 21, threshold_hi: 0x0000000000000036, threshold_lo: 0x35c9adc5dea00000, digits1: 21 }, DecDigits{ digits: 0, threshold_hi: 0x0000000000000036, threshold_lo: 0x35c9adc5dea00000, digits1: 21 }, DecDigits{ digits: 22, threshold_hi: 0x000000000000021e, threshold_lo: 0x19e0c9bab2400000, digits1: 22 }, DecDigits{ digits: 22, threshold_hi: 0x000000000000021e, threshold_lo: 0x19e0c9bab2400000, digits1: 22 }, DecDigits{ digits: 22, threshold_hi: 0x000000000000021e, threshold_lo: 0x19e0c9bab2400000, digits1: 22 }, DecDigits{ digits: 0, threshold_hi: 0x000000000000021e, threshold_lo: 0x19e0c9bab2400000, digits1: 22 }, DecDigits{ digits: 23, threshold_hi: 0x000000000000152d, threshold_lo: 0x02c7e14af6800000, digits1: 23 }, DecDigits{ digits: 23, threshold_hi: 0x000000000000152d, threshold_lo: 0x02c7e14af6800000, digits1: 23 }, DecDigits{ digits: 0, threshold_hi: 0x000000000000152d, threshold_lo: 0x02c7e14af6800000, digits1: 23 }, DecDigits{ digits: 24, threshold_hi: 0x000000000000d3c2, threshold_lo: 0x1bcecceda1000000, digits1: 24 }, DecDigits{ digits: 24, threshold_hi: 0x000000000000d3c2, threshold_lo: 0x1bcecceda1000000, digits1: 24 }, DecDigits{ digits: 0, threshold_hi: 0x000000000000d3c2, threshold_lo: 0x1bcecceda1000000, digits1: 24 }, DecDigits{ digits: 25, threshold_hi: 0x0000000000084595, threshold_lo: 0x161401484a000000, digits1: 25 }, DecDigits{ digits: 25, threshold_hi: 0x0000000000084595, threshold_lo: 0x161401484a000000, digits1: 25 }, DecDigits{ digits: 25, threshold_hi: 0x0000000000084595, threshold_lo: 0x161401484a000000, digits1: 25 }, DecDigits{ digits: 0, threshold_hi: 0x0000000000084595, threshold_lo: 0x161401484a000000, digits1: 25 }, DecDigits{ digits: 26, threshold_hi: 0x000000000052b7d2, threshold_lo: 0xdcc80cd2e4000000, digits1: 26 }, DecDigits{ digits: 26, threshold_hi: 0x000000000052b7d2, threshold_lo: 0xdcc80cd2e4000000, digits1: 26 }, DecDigits{ digits: 0, threshold_hi: 0x000000000052b7d2, threshold_lo: 0xdcc80cd2e4000000, digits1: 26 }, DecDigits{ digits: 27, threshold_hi: 0x00000000033b2e3c, threshold_lo: 0x9fd0803ce8000000, digits1: 27 }, DecDigits{ digits: 27, threshold_hi: 0x00000000033b2e3c, threshold_lo: 0x9fd0803ce8000000, digits1: 27 }, DecDigits{ digits: 0, threshold_hi: 0x00000000033b2e3c, threshold_lo: 0x9fd0803ce8000000, digits1: 27 }, DecDigits{ digits: 28, threshold_hi: 0x00000000204fce5e, threshold_lo: 0x3e25026110000000, digits1: 28 }, DecDigits{ digits: 28, threshold_hi: 0x00000000204fce5e, threshold_lo: 0x3e25026110000000, digits1: 28 }, DecDigits{ digits: 28, threshold_hi: 0x00000000204fce5e, threshold_lo: 0x3e25026110000000, digits1: 28 }, DecDigits{ digits: 0, threshold_hi: 0x00000000204fce5e, threshold_lo: 0x3e25026110000000, digits1: 28 }, DecDigits{ digits: 29, threshold_hi: 0x00000001431e0fae, threshold_lo: 0x6d7217caa0000000, digits1: 29 }, DecDigits{ digits: 29, threshold_hi: 0x00000001431e0fae, threshold_lo: 0x6d7217caa0000000, digits1: 29 }, DecDigits{ digits: 0, threshold_hi: 0x00000001431e0fae, threshold_lo: 0x6d7217caa0000000, digits1: 29 }, DecDigits{ digits: 30, threshold_hi: 0x0000000c9f2c9cd0, threshold_lo: 0x4674edea40000000, digits1: 30 }, DecDigits{ digits: 30, threshold_hi: 0x0000000c9f2c9cd0, threshold_lo: 0x4674edea40000000, digits1: 30 }, DecDigits{ digits: 0, threshold_hi: 0x0000000c9f2c9cd0, threshold_lo: 0x4674edea40000000, digits1: 30 }, DecDigits{ digits: 31, threshold_hi: 0x0000007e37be2022, threshold_lo: 0xc0914b2680000000, digits1: 31 }, DecDigits{ digits: 31, threshold_hi: 0x0000007e37be2022, threshold_lo: 0xc0914b2680000000, digits1: 31 }, DecDigits{ digits: 0, threshold_hi: 0x0000007e37be2022, threshold_lo: 0xc0914b2680000000, digits1: 31 }, DecDigits{ digits: 32, threshold_hi: 0x000004ee2d6d415b, threshold_lo: 0x85acef8100000000, digits1: 32 }, DecDigits{ digits: 32, threshold_hi: 0x000004ee2d6d415b, threshold_lo: 0x85acef8100000000, digits1: 32 }, DecDigits{ digits: 32, threshold_hi: 0x000004ee2d6d415b, threshold_lo: 0x85acef8100000000, digits1: 32 }, DecDigits{ digits: 0, threshold_hi: 0x000004ee2d6d415b, threshold_lo: 0x85acef8100000000, digits1: 32 }, DecDigits{ digits: 33, threshold_hi: 0x0000314dc6448d93, threshold_lo: 0x38c15b0a00000000, digits1: 33 }, DecDigits{ digits: 33, threshold_hi: 0x0000314dc6448d93, threshold_lo: 0x38c15b0a00000000, digits1: 33 }, DecDigits{ digits: 0, threshold_hi: 0x0000314dc6448d93, threshold_lo: 0x38c15b0a00000000, digits1: 33 }, DecDigits{ digits: 34, threshold_hi: 0x0001ed09bead87c0, threshold_lo: 0x378d8e6400000000, digits1: 34 }, DecDigits{ digits: 34, threshold_hi: 0x0001ed09bead87c0, threshold_lo: 0x378d8e6400000000, digits1: 34 }, DecDigits{ digits: 0, threshold_hi: 0x0001ed09bead87c0, threshold_lo: 0x378d8e6400000000, digits1: 34 } ];
macro_rules! bid_ten2k64 {
($index:expr) => {
BID_TEN2K64[$index as usize]
};
}
pub(crate) use bid_ten2k64;
#[rustfmt::skip]
pub const BID_TEN2K64: [u64; 20] = [
0x0000000000000001, 0x000000000000000a, 0x0000000000000064, 0x00000000000003e8, 0x0000000000002710, 0x00000000000186a0, 0x00000000000f4240, 0x0000000000989680, 0x0000000005f5e100, 0x000000003b9aca00, 0x00000002540be400, 0x000000174876e800, 0x000000e8d4a51000, 0x000009184e72a000, 0x00005af3107a4000, 0x00038d7ea4c68000, 0x002386f26fc10000, 0x016345785d8a0000, 0x0de0b6b3a7640000, 0x8ac7230489e80000, ];
macro_rules! bid_ten2k128 {
($index:expr) => {
BID_TEN2K128[$index as usize]
};
}
pub(crate) use bid_ten2k128;
#[rustfmt::skip]
pub const BID_TEN2K128: [BidUint128; 19] = [
BidUint128 { w: [0x6bc75e2d63100000, 0x0000000000000005] }, BidUint128 { w: [0x35c9adc5dea00000, 0x0000000000000036] }, BidUint128 { w: [0x19e0c9bab2400000, 0x000000000000021e] }, BidUint128 { w: [0x02c7e14af6800000, 0x000000000000152d] }, BidUint128 { w: [0x1bcecceda1000000, 0x000000000000d3c2] }, BidUint128 { w: [0x161401484a000000, 0x0000000000084595] }, BidUint128 { w: [0xdcc80cd2e4000000, 0x000000000052b7d2] }, BidUint128 { w: [0x9fd0803ce8000000, 0x00000000033b2e3c] }, BidUint128 { w: [0x3e25026110000000, 0x00000000204fce5e] }, BidUint128 { w: [0x6d7217caa0000000, 0x00000001431e0fae] }, BidUint128 { w: [0x4674edea40000000, 0x0000000c9f2c9cd0] }, BidUint128 { w: [0xc0914b2680000000, 0x0000007e37be2022] }, BidUint128 { w: [0x85acef8100000000, 0x000004ee2d6d415b] }, BidUint128 { w: [0x38c15b0a00000000, 0x0000314dc6448d93] }, BidUint128 { w: [0x378d8e6400000000, 0x0001ed09bead87c0] }, BidUint128 { w: [0x2b878fe800000000, 0x0013426172c74d82] }, BidUint128 { w: [0xb34b9f1000000000, 0x00c097ce7bc90715] }, BidUint128 { w: [0x00f436a000000000, 0x0785ee10d5da46d9] }, BidUint128 { w: [0x098a224000000000, 0x4b3b4ca85a86c47a] }, ];
macro_rules! bid_midpoint64 {
($index:expr) => {
BID_MIDPOINT64[$index as usize]
};
}
pub(crate) use bid_midpoint64;
#[rustfmt::skip]
pub const BID_MIDPOINT64: [u64; 19] = [
0x0000000000000005, 0x0000000000000032, 0x00000000000001f4, 0x0000000000001388, 0x000000000000c350, 0x000000000007a120, 0x00000000004c4b40, 0x0000000002faf080, 0x000000001dcd6500, 0x000000012a05f200, 0x0000000ba43b7400, 0x000000746a528800, 0x0000048c27395000, 0x00002d79883d2000, 0x0001c6bf52634000, 0x0011c37937e08000, 0x00b1a2bc2ec50000, 0x06f05b59d3b20000, 0x4563918244f40000, ];
macro_rules! bid_midpoint128 {
($index:expr) => {
BID_MIDPOINT128[$index as usize]
};
}
pub(crate) use bid_midpoint128;
#[rustfmt::skip]
pub const BID_MIDPOINT128: [BidUint128; 19] = [
BidUint128 { w: [0xb5e3af16b1880000, 0x0000000000000002] }, BidUint128 { w: [0x1ae4d6e2ef500000, 0x000000000000001b] }, BidUint128 { w: [0x0cf064dd59200000, 0x000000000000010f] }, BidUint128 { w: [0x8163f0a57b400000, 0x0000000000000a96] }, BidUint128 { w: [0x0de76676d0800000, 0x00000000000069e1] }, BidUint128 { w: [0x8b0a00a425000000, 0x00000000000422ca] }, BidUint128 { w: [0x6e64066972000000, 0x0000000000295be9] }, BidUint128 { w: [0x4fe8401e74000000, 0x00000000019d971e] }, BidUint128 { w: [0x1f12813088000000, 0x000000001027e72f] }, BidUint128 { w: [0x36b90be550000000, 0x00000000a18f07d7] }, BidUint128 { w: [0x233a76f520000000, 0x000000064f964e68] }, BidUint128 { w: [0x6048a59340000000, 0x0000003f1bdf1011] }, BidUint128 { w: [0xc2d677c080000000, 0x0000027716b6a0ad] }, BidUint128 { w: [0x9c60ad8500000000, 0x000018a6e32246c9] }, BidUint128 { w: [0x1bc6c73200000000, 0x0000f684df56c3e0] }, BidUint128 { w: [0x15c3c7f400000000, 0x0009a130b963a6c1] }, BidUint128 { w: [0xd9a5cf8800000000, 0x00604be73de4838a] }, BidUint128 { w: [0x807a1b5000000000, 0x03c2f7086aed236c] }, BidUint128 { w: [0x04c5112000000000, 0x259da6542d43623d] }, ];
macro_rules! bid_ten2k256 {
($index:expr) => {
BID_TEN2K256[$index as usize]
};
}
pub(crate) use bid_ten2k256;
#[rustfmt::skip]
pub const BID_TEN2K256: [BidUint256;39] = [
BidUint256{ w: [0x5f65568000000000, 0xf050fe938943acc4, 0x0000000000000002, 0x0000000000000000]}, BidUint256{ w: [0xb9f5610000000000, 0x6329f1c35ca4bfab, 0x000000000000001d, 0x0000000000000000]}, BidUint256{ w: [0x4395ca0000000000, 0xdfa371a19e6f7cb5, 0x0000000000000125, 0x0000000000000000]}, BidUint256{ w: [0xa3d9e40000000000, 0xbc627050305adf14, 0x0000000000000b7a, 0x0000000000000000]}, BidUint256{ w: [0x6682e80000000000, 0x5bd86321e38cb6ce, 0x00000000000072cb, 0x0000000000000000]}, BidUint256{ w: [0x011d100000000000, 0x9673df52e37f2410, 0x0000000000047bf1, 0x0000000000000000]}, BidUint256{ w: [0x0b22a00000000000, 0xe086b93ce2f768a0, 0x00000000002cd76f, 0x0000000000000000]}, BidUint256{ w: [0x6f5a400000000000, 0xc5433c60ddaa1640, 0x0000000001c06a5e, 0x0000000000000000]}, BidUint256{ w: [0x5986800000000000, 0xb4a05bc8a8a4de84, 0x00000000118427b3, 0x0000000000000000]}, BidUint256{ w: [0x7f41000000000000, 0x0e4395d69670b12b, 0x00000000af298d05, 0x0000000000000000]}, BidUint256{ w: [0xf88a000000000000, 0x8ea3da61e066ebb2, 0x00000006d79f8232, 0x0000000000000000]}, BidUint256{ w: [0xb564000000000000, 0x926687d2c40534fd, 0x000000446c3b15f9, 0x0000000000000000]}, BidUint256{ w: [0x15e8000000000000, 0xb8014e3ba83411e9, 0x000002ac3a4edbbf, 0x0000000000000000]}, BidUint256{ w: [0xdb10000000000000, 0x300d0e549208b31a, 0x00001aba4714957d, 0x0000000000000000]}, BidUint256{ w: [0x8ea0000000000000, 0xe0828f4db456ff0c, 0x00010b46c6cdd6e3, 0x0000000000000000]}, BidUint256{ w: [0x9240000000000000, 0xc51999090b65f67d, 0x000a70c3c40a64e6, 0x0000000000000000]}, BidUint256{ w: [0xb680000000000000, 0xb2fffa5a71fba0e7, 0x006867a5a867f103, 0x0000000000000000]}, BidUint256{ w: [0x2100000000000000, 0xfdffc78873d4490d, 0x04140c78940f6a24, 0x0000000000000000]}, BidUint256{ w: [0x4a00000000000000, 0xebfdcb54864ada83, 0x28c87cb5c89a2571, 0x0000000000000000]}, BidUint256{ w: [0xe400000000000000, 0x37e9f14d3eec8920, 0x97d4df19d6057673, 0x0000000000000001]}, BidUint256{ w: [0xe800000000000000, 0x2f236d04753d5b48, 0xee50b7025c36a080, 0x000000000000000f]}, BidUint256{ w: [0x1000000000000000, 0xd762422c946590d9, 0x4f2726179a224501, 0x000000000000009f]}, BidUint256{ w: [0xa000000000000000, 0x69d695bdcbf7a87a, 0x17877cec0556b212, 0x0000000000000639]}, BidUint256{ w: [0x4000000000000000, 0x2261d969f7ac94ca, 0xeb4ae1383562f4b8, 0x0000000000003e3a]}, BidUint256{ w: [0x8000000000000000, 0x57d27e23acbdcfe6, 0x30eccc3215dd8f31, 0x0000000000026e4d]}, BidUint256{ w: [0x0000000000000000, 0x6e38ed64bf6a1f01, 0xe93ff9f4daa797ed, 0x0000000000184f03]}, BidUint256{ w: [0x0000000000000000, 0x4e3945ef7a25360a, 0x1c7fc3908a8bef46, 0x0000000000f31627]}, BidUint256{ w: [0x0000000000000000, 0x0e3cbb5ac5741c64, 0x1cfda3a5697758bf, 0x00000000097edd87]}, BidUint256{ w: [0x0000000000000000, 0x8e5f518bb6891be8, 0x21e864761ea97776, 0x000000005ef4a747]}, BidUint256{ w: [0x0000000000000000, 0x8fb92f75215b1710, 0x5313ec9d329eaaa1, 0x00000003b58e88c7]}, BidUint256{ w: [0x0000000000000000, 0x9d3bda934d8ee6a0, 0x3ec73e23fa32aa4f, 0x00000025179157c9]}, BidUint256{ w: [0x0000000000000000, 0x245689c107950240, 0x73c86d67c5faa71c, 0x00000172ebad6ddc]}, BidUint256{ w: [0x0000000000000000, 0x6b61618a4bd21680, 0x85d4460dbbca8719, 0x00000e7d34c64a9c]}, BidUint256{ w: [0x0000000000000000, 0x31cdcf66f634e100, 0x3a4abc8955e946fe, 0x000090e40fbeea1d]}, BidUint256{ w: [0x0000000000000000, 0xf20a1a059e10ca00, 0x46eb5d5d5b1cc5ed, 0x0005a8e89d752524]}, BidUint256{ w: [0x0000000000000000, 0x746504382ca7e400, 0xc531a5a58f1fbb4b, 0x003899162693736a]}, BidUint256{ w: [0x0000000000000000, 0x8bf22a31be8ee800, 0xb3f07877973d50f2, 0x0235fadd81c2822b]}, BidUint256{ w: [0x0000000000000000, 0x7775a5f171951000, 0x0764b4abe8652979, 0x161bcca7119915b5]}, BidUint256{ w: [0x0000000000000000, 0xaa987b6e6fd2a000, 0x49ef0eb713f39ebe, 0xdd15fe86affad912]} ];
macro_rules! bid_ten2mk128 {
($index:expr) => {
BID_TEN2MK128[$index as usize]
};
}
pub(crate) use bid_ten2mk128;
#[rustfmt::skip]
pub const BID_TEN2MK128: [BidUint128; 34] = [
BidUint128{ w: [0x999999999999999a, 0x1999999999999999] }, BidUint128{ w: [0x28f5c28f5c28f5c3, 0x028f5c28f5c28f5c] }, BidUint128{ w: [0x9db22d0e56041894, 0x004189374bc6a7ef] }, BidUint128{ w: [0x4af4f0d844d013aa, 0x00346dc5d6388659] }, BidUint128{ w: [0x08c3f3e0370cdc88, 0x0029f16b11c6d1e1] }, BidUint128{ w: [0x6d698fe69270b06d, 0x00218def416bdb1a] }, BidUint128{ w: [0xaf0f4ca41d811a47, 0x0035afe535795e90] }, BidUint128{ w: [0xbf3f70834acdaea0, 0x002af31dc4611873] }, BidUint128{ w: [0x65cc5a02a23e254d, 0x00225c17d04dad29] }, BidUint128{ w: [0x6fad5cd10396a214, 0x0036f9bfb3af7b75] }, BidUint128{ w: [0xbfbde3da69454e76, 0x002bfaffc2f2c92a] }, BidUint128{ w: [0x32fe4fe1edd10b92, 0x00232f33025bd422] }, BidUint128{ w: [0x84ca19697c81ac1c, 0x00384b84d092ed03] }, BidUint128{ w: [0x03d4e1213067bce4, 0x002d09370d425736] }, BidUint128{ w: [0x3643e74dc052fd83, 0x0024075f3dceac2b] }, BidUint128{ w: [0x56d30baf9a1e626b, 0x0039a5652fb11378] }, BidUint128{ w: [0x12426fbfae7eb522, 0x002e1dea8c8da92d] }, BidUint128{ w: [0x41cebfcc8b9890e8, 0x0024e4bba3a48757] }, BidUint128{ w: [0x694acc7a78f41b0d, 0x003b07929f6da558] }, BidUint128{ w: [0xbaa23d2ec729af3e, 0x002f394219248446] }, BidUint128{ w: [0xfbb4fdbf05baf298, 0x0025c768141d369e] }, BidUint128{ w: [0x2c54c931a2c4b759, 0x003c7240202ebdcb] }, BidUint128{ w: [0x89dd6dc14f03c5e1, 0x00305b66802564a2] }, BidUint128{ w: [0xd4b1249aa59c9e4e, 0x0026af8533511d4e] }, BidUint128{ w: [0x544ea0f76f60fd49, 0x003de5a1ebb4fbb1] }, BidUint128{ w: [0x76a54d92bf80caa1, 0x00318481895d9627] }, BidUint128{ w: [0x921dd7a89933d54e, 0x00279d346de4781f] }, BidUint128{ w: [0x8362f2a75b862215, 0x003f61ed7ca0c032] }, BidUint128{ w: [0xcf825bb91604e811, 0x0032b4bdfd4d668e] }, BidUint128{ w: [0x0c684960de6a5341, 0x00289097fdd7853f] }, BidUint128{ w: [0x3d203ab3e521dc34, 0x002073accb12d0ff] }, BidUint128{ w: [0x2e99f7863b696053, 0x0033ec47ab514e65] }, BidUint128{ w: [0x587b2c6b62bab376, 0x002989d2ef743eb7] }, BidUint128{ w: [0xad2f56bc4efbc2c5, 0x00213b0f25f69892] }, ];
macro_rules! bid_maskhigh128 {
($index:expr) => {
BID_MASKHIGH128[$index as usize]
};
}
pub(crate) use bid_maskhigh128;
#[rustfmt::skip]
pub const BID_MASKHIGH128: [BidUint64; 34] = [
0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000007, 0x000000000000003f, 0x00000000000001ff, 0x0000000000001fff, 0x000000000000ffff, 0x000000000007ffff, 0x00000000007fffff, 0x0000000003ffffff, 0x000000001fffffff, 0x00000001ffffffff, 0x0000000fffffffff, 0x0000007fffffffff, 0x000007ffffffffff, 0x00003fffffffffff, 0x0001ffffffffffff, 0x001fffffffffffff, 0x00ffffffffffffff, 0x07ffffffffffffff, 0x7fffffffffffffff, 0x0000000000000003, 0x000000000000001f, 0x00000000000001ff, 0x0000000000000fff, 0x0000000000007fff, 0x000000000007ffff, 0x00000000003fffff, 0x0000000001ffffff, 0x000000000fffffff, 0x00000000ffffffff, 0x00000007ffffffff, 0x0000003fffffffff ];
macro_rules! bid_shiftright128 {
($index:expr) => {
BID_SHIFTRIGHT128[$index as usize]
};
}
pub(crate) use bid_shiftright128;
#[rustfmt::skip]
pub const BID_SHIFTRIGHT128: [i32; 34] = [
0, 0, 0, 3, 6, 9, 13, 16, 19, 23, 26, 29, 33, 36, 39, 43, 46, 49, 53, 56, 59, 63, 66, 69, 73, 76, 79, 83, 86, 89, 92, 96, 99, 102, ];
macro_rules! bid_ten2mk128trunc {
($index:expr) => {
BID_TEN2MK128TRUNC[$index as usize]
};
}
pub(crate) use bid_ten2mk128trunc;
#[rustfmt::skip]
pub const BID_TEN2MK128TRUNC:[BidUint128; 34] = [
BidUint128{ w: [0x9999999999999999, 0x1999999999999999] }, BidUint128{ w: [0x28f5c28f5c28f5c2, 0x028f5c28f5c28f5c] }, BidUint128{ w: [0x9db22d0e56041893, 0x004189374bc6a7ef] }, BidUint128{ w: [0x4af4f0d844d013a9, 0x00346dc5d6388659] }, BidUint128{ w: [0x08c3f3e0370cdc87, 0x0029f16b11c6d1e1] }, BidUint128{ w: [0x6d698fe69270b06c, 0x00218def416bdb1a] }, BidUint128{ w: [0xaf0f4ca41d811a46, 0x0035afe535795e90] }, BidUint128{ w: [0xbf3f70834acdae9f, 0x002af31dc4611873] }, BidUint128{ w: [0x65cc5a02a23e254c, 0x00225c17d04dad29] }, BidUint128{ w: [0x6fad5cd10396a213, 0x0036f9bfb3af7b75] }, BidUint128{ w: [0xbfbde3da69454e75, 0x002bfaffc2f2c92a] }, BidUint128{ w: [0x32fe4fe1edd10b91, 0x00232f33025bd422] }, BidUint128{ w: [0x84ca19697c81ac1b, 0x00384b84d092ed03] }, BidUint128{ w: [0x03d4e1213067bce3, 0x002d09370d425736] }, BidUint128{ w: [0x3643e74dc052fd82, 0x0024075f3dceac2b] }, BidUint128{ w: [0x56d30baf9a1e626a, 0x0039a5652fb11378] }, BidUint128{ w: [0x12426fbfae7eb521, 0x002e1dea8c8da92d] }, BidUint128{ w: [0x41cebfcc8b9890e7, 0x0024e4bba3a48757] }, BidUint128{ w: [0x694acc7a78f41b0c, 0x003b07929f6da558] }, BidUint128{ w: [0xbaa23d2ec729af3d, 0x002f394219248446] }, BidUint128{ w: [0xfbb4fdbf05baf297, 0x0025c768141d369e] }, BidUint128{ w: [0x2c54c931a2c4b758, 0x003c7240202ebdcb] }, BidUint128{ w: [0x89dd6dc14f03c5e0, 0x00305b66802564a2] }, BidUint128{ w: [0xd4b1249aa59c9e4d, 0x0026af8533511d4e] }, BidUint128{ w: [0x544ea0f76f60fd48, 0x003de5a1ebb4fbb1] }, BidUint128{ w: [0x76a54d92bf80caa0, 0x00318481895d9627] }, BidUint128{ w: [0x921dd7a89933d54d, 0x00279d346de4781f] }, BidUint128{ w: [0x8362f2a75b862214, 0x003f61ed7ca0c032] }, BidUint128{ w: [0xcf825bb91604e810, 0x0032b4bdfd4d668e] }, BidUint128{ w: [0x0c684960de6a5340, 0x00289097fdd7853f] }, BidUint128{ w: [0x3d203ab3e521dc33, 0x002073accb12d0ff] }, BidUint128{ w: [0x2e99f7863b696052, 0x0033ec47ab514e65] }, BidUint128{ w: [0x587b2c6b62bab375, 0x002989d2ef743eb7] }, BidUint128{ w: [0xad2f56bc4efbc2c4, 0x00213b0f25f69892] }, ];
macro_rules! bid_onehalf128 {
($index:expr) => {
BID_ONEHALF128[$index as usize]
};
}
pub(crate) use bid_onehalf128;
#[rustfmt::skip]
pub const BID_ONEHALF128: [BidUint64; 34] = [
0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000004, 0x0000000000000020, 0x0000000000000100, 0x0000000000001000, 0x0000000000008000, 0x0000000000040000, 0x0000000000400000, 0x0000000002000000, 0x0000000010000000, 0x0000000100000000, 0x0000000800000000, 0x0000004000000000, 0x0000040000000000, 0x0000200000000000, 0x0001000000000000, 0x0010000000000000, 0x0080000000000000, 0x0400000000000000, 0x4000000000000000, 0x0000000000000002, 0x0000000000000010, 0x0000000000000100, 0x0000000000000800, 0x0000000000004000, 0x0000000000040000, 0x0000000000200000, 0x0000000001000000, 0x0000000008000000, 0x0000000080000000, 0x0000000400000000, 0x0000002000000000, ];
macro_rules! add_128_64 {
($r:expr,$x:expr,$y:expr) => {
let mut rh: BidUint64 = $x.w[1];
$r.w[0] = $y.wrapping_add($x.w[0]);
if $r.w[0] < $y {
rh = rh.wrapping_add(1);
}
$r.w[1] = rh;
};
}
pub(crate) use add_128_64;
macro_rules! add_128_128 {
($r128:expr, $a128:expr, $b128:expr) => {
let mut q128: BidUint128 = BidUint128::default();
q128.w[1] = $a128.w[1].wrapping_add($b128.w[1]);
q128.w[0] = $b128.w[0].wrapping_add($a128.w[0]);
if q128.w[0] < $b128.w[0] {
q128.w[1] = q128.w[1].wrapping_add(1);
}
$r128.w[1] = q128.w[1];
$r128.w[0] = q128.w[0];
};
}
pub(crate) use add_128_128;
macro_rules! sub_128_128 {
($r128:expr, $a128:expr, $b128:expr) => {
let mut q128: BidUint128 = Default::default();
q128.w[1] = $a128.w[1].wrapping_sub($b128.w[1]);
q128.w[0] = $a128.w[0].wrapping_sub($b128.w[0]);
if $a128.w[0] < $b128.w[0] {
q128.w[1] = q128.w[1].wrapping_sub(1);
}
$r128.w[1] = q128.w[1];
$r128.w[0] = q128.w[0];
};
}
pub(crate) use sub_128_128;
macro_rules! add_carry_out {
($r:expr, $co:expr, $x:expr, $y: expr) => {
$r = $x.wrapping_add($y);
$co = if $r < $x { 1 } else { 0 };
};
}
pub(crate) use add_carry_out;
macro_rules! add_carry_in_out {
($r:expr, $co:expr, $x:expr, $y:expr, $ci:expr) => {
let x1: BidUint64 = $x.wrapping_add($ci);
$r = x1.wrapping_add($y);
$co = if ($r < x1) || (x1 < $ci) { 1 } else { 0 }
};
}
pub(crate) use add_carry_in_out;
macro_rules! mul_64x64_to_64 {
($p64:expr, $cx:expr, $cy:expr) => {
$p64 = $cx.wrapping_mul($cy);
};
}
pub(crate) use mul_64x64_to_64;
macro_rules! sub_borrow_out {
($s:expr, $cy:expr, $x:expr, $y:expr) => {
let x1: BidUint64 = $x;
$s = $x.wrapping_sub($y);
$cy = if $s > x1 { 1 } else { 0 };
};
}
pub(crate) use sub_borrow_out;
macro_rules! sub_borrow_in_out {
($s:expr, $cy:expr, $x:expr, $y:expr, $ci:expr) => {
let x0: BidUint64 = $x;
let x1: BidUint64 = $x.wrapping_sub($ci);
$s = x1.wrapping_sub($y);
$cy = if ($s > x1) || (x1 > x0) { 1 } else { 0 };
};
}
pub(crate) use sub_borrow_in_out;
macro_rules! mul_64x64_to_128mach {
($p:expr, $cx:expr, $cy:expr) => {
let cxh: BidUint64 = (($cx >> 32) as u32) as u64;
let cxl: BidUint64 = ($cx as u32) as u64;
let cyh: BidUint64 = (($cy >> 32) as u32) as u64;
let cyl: BidUint64 = ($cy as u32) as u64;
let mut pm: BidUint64 = cxh.wrapping_mul(cyl);
let mut ph: BidUint64 = cxh.wrapping_mul(cyh);
let pl: BidUint64 = cxl.wrapping_mul(cyl);
let pm2: BidUint64 = cxl.wrapping_mul(cyh);
ph = ph.wrapping_add(((pm >> 32) as u32) as u64);
pm = ((pm as u32) as u64).wrapping_add(pm2).wrapping_add(((pl >> 32) as u32) as u64);
$p.w[1] = ph.wrapping_add(((pm >> 32) as u32) as u64);
$p.w[0] = (pm << 32).wrapping_add((pl as u32) as u64);
};
}
pub(crate) use mul_64x64_to_128mach;
macro_rules! mul_64x64_to_128 {
($p:expr,$cx:expr,$cy:expr) => {
let cxh: BidUint64 = (($cx >> 32) as u32) as u64;
let cxl: BidUint64 = ($cx as u32) as u64;
let cyh: BidUint64 = (($cy >> 32) as u32) as u64;
let cyl: BidUint64 = ($cy as u32) as u64;
let mut pm = cxh.wrapping_mul(cyl);
let mut ph = cxh.wrapping_mul(cyh);
let pl = cxl.wrapping_mul(cyl);
let pm2 = cxl.wrapping_mul(cyh);
ph = ph.wrapping_add(((pm >> 32) as u32) as u64);
pm = ((pm as u32) as u64).wrapping_add(pm2).wrapping_add(((pl >> 32) as u32) as u64);
$p.w[1] = ph.wrapping_add(((pm >> 32) as u32) as u64);
$p.w[0] = (pm << 32).wrapping_add((pl as u32) as u64);
};
}
pub(crate) use mul_64x64_to_128;
macro_rules! mul_64x128_to_128 {
($ql:expr, $a:expr, $b:expr) => {
let mut albl: BidUint128 = Default::default();
let mut albh: BidUint128 = Default::default();
let mut qm2: BidUint128 = Default::default();
mul_64x64_to_128!(albh, $a, $b.w[1]);
mul_64x64_to_128!(albl, $a, $b.w[0]);
$ql.w[0] = albl.w[0];
add_128_64!(qm2, albh, albl.w[1]);
$ql.w[1] = qm2.w[0];
};
}
pub(crate) use mul_64x128_to_128;
macro_rules! mul_64x128_short {
($ql:expr, $a:expr, $b:expr) => {
let albh_l: BidUint64;
mul_64x64_to_64!(albh_l, $a, $b.w[1]);
mul_64x64_to_128!($ql, $a, $b.w[0]);
$ql.w[1] = $ql.w[1].wrapping_add(albh_l);
};
}
pub(crate) use mul_64x128_short;
macro_rules! mul_128x64_to_128 {
($q128:expr, $a64:expr, $b128:expr) => {
let albh_l: BidUint64 = $a64.wrapping_mul($b128.w[1]);
mul_64x64_to_128mach!($q128, $a64, $b128.w[0]);
$q128.w[1] = $q128.w[1].wrapping_add(albh_l);
};
}
pub(crate) use mul_128x64_to_128;
macro_rules! mul_64x256_to_320 {
($p:expr, $a:expr, $b:expr) => {
let mut p0: BidUint128 = Default::default();
let mut p1: BidUint128 = Default::default();
let mut p2: BidUint128 = Default::default();
let mut p3: BidUint128 = Default::default();
let mut cy: BidUint64;
mul_64x64_to_128!(p0, $a, $b.w[0]);
mul_64x64_to_128!(p1, $a, $b.w[1]);
mul_64x64_to_128!(p2, $a, $b.w[2]);
mul_64x64_to_128!(p3, $a, $b.w[3]);
$p.w[0] = p0.w[0];
add_carry_out!($p.w[1], cy, p1.w[0], p0.w[1]);
add_carry_in_out!($p.w[2], cy, p2.w[0], p1.w[1], cy);
add_carry_in_out!($p.w[3], cy, p3.w[0], p2.w[1], cy);
$p.w[4] = p3.w[1].wrapping_add(cy);
};
}
pub(crate) use mul_64x256_to_320;
macro_rules! mul_64x128_full {
($ph:expr, $ql:expr, $x:expr, $y:expr) => {
let mut albl = BidUint128::default();
let mut albh = BidUint128::default();
mul_64x64_to_128!(albh, $x, $y.w[1]);
mul_64x64_to_128!(albl, $x, $y.w[0]);
$ql.w[0] = albl.w[0];
let mut qm2 = BidUint128::default();
add_128_64!(qm2, albh, albl.w[1]);
$ql.w[1] = qm2.w[0];
$ph = qm2.w[1];
};
}
pub(crate) use mul_64x128_full;
macro_rules! mul_64x128_to_192 {
($q:expr, $a:expr, $b:expr) => {
let mut albl: BidUint128 = Default::default();
let mut albh: BidUint128 = Default::default();
let mut qm2: BidUint128 = Default::default();
mul_64x64_to_128!(albh, $a, $b.w[1]);
mul_64x64_to_128!(albl, $a, $b.w[0]);
$q.w[0] = albl.w[0];
add_128_64!(qm2, albh, albl.w[1]);
$q.w[1] = qm2.w[0];
$q.w[2] = qm2.w[1];
};
}
pub(crate) use mul_64x128_to_192;
macro_rules! mul_64x192_to_256 {
($lP:expr, $lA:expr, $lB:expr) => {
let mut p0: BidUint128 = Default::default();
let mut p1: BidUint128 = Default::default();
let mut p2: BidUint128 = Default::default();
let mut cy: BidUint64;
mul_64x64_to_128!(p0, $lA, $lB.w[0]);
mul_64x64_to_128!(p1, $lA, $lB.w[1]);
mul_64x64_to_128!(p2, $lA, $lB.w[2]);
$lP.w[0] = p0.w[0];
add_carry_out!($lP.w[1], cy, p1.w[0], p0.w[1]);
add_carry_in_out!($lP.w[2], cy, p2.w[0], p1.w[1], cy);
$lP.w[3] = p2.w[1].wrapping_add(cy);
};
}
pub(crate) use mul_64x192_to_256;
macro_rules! mul_128x128_to_256 {
($r:expr, $x:expr, $y:expr) => {
let mut qll = BidUint128::default();
let mut qlh = BidUint128::default();
let phl: BidUint64;
let phh: BidUint64;
let co1: BidUint64;
let co2: BidUint64;
mul_64x128_full!(phl, qll, $x.w[0], $y);
mul_64x128_full!(phh, qlh, $x.w[1], $y);
$r.w[0] = qll.w[0];
add_carry_out!($r.w[1], co1, qlh.w[0], qll.w[1]);
add_carry_in_out!($r.w[2], co2, qlh.w[1], phl, co1);
$r.w[3] = phh.wrapping_add(co2);
};
}
pub(crate) use mul_128x128_to_256;
macro_rules! mul_128x128_full {
($qh:expr, $ql:expr, $a:expr, $b:expr) => {
let mut albl: BidUint128 = BidUint128::default();
let mut albh: BidUint128 = BidUint128::default();
let mut ahbl: BidUint128 = BidUint128::default();
let mut ahbh: BidUint128 = BidUint128::default();
let mut qm: BidUint128 = BidUint128::default();
let mut qm2: BidUint128 = BidUint128::default();
mul_64x64_to_128!(albh, $a.w[0], $b.w[1]);
mul_64x64_to_128!(ahbl, $b.w[0], $a.w[1]);
mul_64x64_to_128!(albl, $a.w[0], $b.w[0]);
mul_64x64_to_128!(ahbh, $a.w[1], $b.w[1]);
add_128_128!(qm, albh, ahbl);
$ql.w[0] = albl.w[0];
add_128_64!(qm2, qm, albl.w[1]);
add_128_64!($qh, ahbh, qm2.w[1]);
$ql.w[1] = qm2.w[0];
};
}
pub(crate) use mul_128x128_full;
macro_rules! mul_128x128_low {
($ql:expr, $a:expr, $b:expr) => {
let mut albl: BidUint128 = Default::default();
mul_64x64_to_128!(albl, $a.w[0], $b.w[0]);
let qm64: BidUint64 = $b.w[0].wrapping_mul($a.w[1]).wrapping_add($a.w[0].wrapping_mul($b.w[1]));
$ql.w[0] = albl.w[0];
$ql.w[1] = qm64.wrapping_add(albl.w[1]);
};
}
pub(crate) use mul_128x128_low;
macro_rules! mul_64x64_to_128_fast {
($p:expr, $cx:expr, $cy:expr) => {
let cxh: BidUint64 = (($cx >> 32) as u32) as u64;
let cxl: BidUint64 = ($cx as u32) as u64;
let cyh: BidUint64 = (($cy >> 32) as u32) as u64;
let cyl: BidUint64 = ($cy as u32) as u64;
let mut pm = cxh * cyl;
let pl: BidUint64 = cxl * cyl;
let ph: BidUint64 = cxh * cyh;
pm += cxl * cyh;
pm += pl >> 32;
$p.w[1] = ph.wrapping_add(((pm >> 32) as u32) as u64);
$p.w[0] = (pm << 32).wrapping_add((pl as u32) as u64);
};
}
pub(crate) use mul_64x64_to_128_fast;
macro_rules! mul_192x192_to_384 {
($p:expr, $a:expr, $b:expr) => {
let mut p0: BidUint256 = Default::default();
let mut p1: BidUint256 = Default::default();
let mut p2: BidUint256 = Default::default();
let mut cy: BidUint64;
mul_64x192_to_256!(p0, $a.w[0], $b);
mul_64x192_to_256!(p1, $a.w[1], $b);
mul_64x192_to_256!(p2, $a.w[2], $b);
$p.w[0] = p0.w[0];
add_carry_out!($p.w[1], cy, p1.w[0], p0.w[1]);
add_carry_in_out!($p.w[2], cy, p1.w[1], p0.w[2], cy);
add_carry_in_out!($p.w[3], cy, p1.w[2], p0.w[3], cy);
$p.w[4] = p1.w[3].wrapping_add(cy);
add_carry_out!($p.w[2], cy, p2.w[0], $p.w[2]);
add_carry_in_out!($p.w[3], cy, p2.w[1], $p.w[3], cy);
add_carry_in_out!($p.w[4], cy, p2.w[2], $p.w[4], cy);
$p.w[5] = p2.w[3].wrapping_add(cy);
};
}
pub(crate) use mul_192x192_to_384;
macro_rules! mul_256x256_to_512 {
($p:expr, $a:expr, $b:expr) => {
let mut p0: BidUint512 = Default::default();
let mut p1: BidUint512 = Default::default();
let mut p2: BidUint512 = Default::default();
let mut p3: BidUint512 = Default::default();
let mut cy: BidUint64;
mul_64x256_to_320!(p0, $a.w[0], $b);
mul_64x256_to_320!(p1, $a.w[1], $b);
mul_64x256_to_320!(p2, $a.w[2], $b);
mul_64x256_to_320!(p3, $a.w[3], $b);
$p.w[0] = p0.w[0];
add_carry_out!($p.w[1], cy, p1.w[0], p0.w[1]);
add_carry_in_out!($p.w[2], cy, p1.w[1], p0.w[2], cy);
add_carry_in_out!($p.w[3], cy, p1.w[2], p0.w[3], cy);
add_carry_in_out!($p.w[4], cy, p1.w[3], p0.w[4], cy);
$p.w[5] = p1.w[4].wrapping_add(cy);
add_carry_out!($p.w[2], cy, p2.w[0], $p.w[2]);
add_carry_in_out!($p.w[3], cy, p2.w[1], $p.w[3], cy);
add_carry_in_out!($p.w[4], cy, p2.w[2], $p.w[4], cy);
add_carry_in_out!($p.w[5], cy, p2.w[3], $p.w[5], cy);
$p.w[6] = p2.w[4].wrapping_add(cy);
add_carry_out!($p.w[3], cy, p3.w[0], $p.w[3]);
add_carry_in_out!($p.w[4], cy, p3.w[1], $p.w[4], cy);
add_carry_in_out!($p.w[5], cy, p3.w[2], $p.w[5], cy);
add_carry_in_out!($p.w[6], cy, p3.w[3], $p.w[6], cy);
$p.w[7] = p3.w[4].wrapping_add(cy);
};
}
pub(crate) use mul_256x256_to_512;
macro_rules! shl_128_long {
($q:expr, $a:expr, $k:expr) => {
if $k < 64 {
$q.w[1] = $a.w[1] << $k;
$q.w[1] |= $a.w[0] >> (64 - $k);
$q.w[0] = $a.w[0] << $k;
} else {
$q.w[1] = $a.w[0] << (($k) - 64);
$q.w[0] = 0;
}
};
}
macro_rules! shr_128_long {
($q:expr, $a:expr, $k:expr) => {
if $k < 64 {
$q.w[0] = $a.w[0] >> $k;
$q.w[0] |= $a.w[1] << (64 - $k);
$q.w[1] = $a.w[1] >> $k;
} else {
$q.w[0] = $a.w[1] >> (($k) - 64);
$q.w[1] = 0;
}
};
}
pub(crate) use shr_128_long;
macro_rules! unsigned_compare_gt_128 {
($a:expr, $b:expr) => {
($a.w[1] > $b.w[1]) || (($a.w[1] == $b.w[1]) && ($a.w[0] > $b.w[0]))
};
}
pub(crate) use unsigned_compare_gt_128;
macro_rules! unsigned_compare_ge_128 {
($a:expr, $b:expr) => {
($a.w[1] > $b.w[1]) || (($a.w[1] == $b.w[1]) && ($a.w[0] >= $b.w[0]))
};
}
pub(crate) use unsigned_compare_ge_128;
macro_rules! shr_128 {
($q:expr, $a:expr, $k:expr) => {
$q.w[0] = $a.w[0] >> $k;
$q.w[0] |= $a.w[1] << (64 - $k);
$q.w[1] = $a.w[1] >> $k;
};
}
pub(crate) use shr_128;
#[inline(always)]
pub fn bid_get_bid128(pres: &mut BidUint128, sgn: BidUint64, mut expon: i32, mut coeff: BidUint128, rnd_mode: IdecRound, pfpsf: &mut IdecFlags) -> BidUint128 {
if coeff.w[1] == 0x0001ed09bead87c0 && coeff.w[0] == 0x378d8e6400000000 {
expon += 1;
coeff.w[1] = 0x0000314dc6448d93;
coeff.w[0] = 0x38c15b0a00000000;
}
if !(0..=DECIMAL_MAX_EXPON_128).contains(&expon) {
if expon < 0 {
return handle_uf_128(pres, sgn, &mut expon, coeff, rnd_mode, pfpsf);
}
if expon - MAX_FORMAT_DIGITS_128 <= DECIMAL_MAX_EXPON_128 {
let t = bid_power10_table_128!(MAX_FORMAT_DIGITS_128 - 1);
while unsigned_compare_gt_128!(t, coeff) && expon > DECIMAL_MAX_EXPON_128 {
coeff.w[1] = (coeff.w[1] << 3).wrapping_add(coeff.w[1] << 1).wrapping_add(coeff.w[0] >> 61).wrapping_add(coeff.w[0] >> 63);
let tmp2 = coeff.w[0] << 3;
coeff.w[0] = (coeff.w[0] << 1).wrapping_add(tmp2);
if coeff.w[0] < tmp2 {
coeff.w[1] = coeff.w[1].wrapping_add(1);
}
expon = expon.wrapping_sub(1);
}
}
if expon > DECIMAL_MAX_EXPON_128 {
if coeff.w[1] | coeff.w[0] == 0 {
pres.w[1] = sgn | ((DECIMAL_MAX_EXPON_128 as u64) << 49);
pres.w[0] = 0;
return *pres;
}
if cfg!(feature = "bid-set-status-flags") {
set_status_flags!(pfpsf, BID_OVERFLOW_EXCEPTION | BID_INEXACT_EXCEPTION);
}
if cfg!(not(feature = "ieee-round-nearest-ties-away")) && cfg!(not(feature = "ieee-round-nearest")) {
if rnd_mode == BID_ROUNDING_TO_ZERO || (sgn > 0 && rnd_mode == BID_ROUNDING_UP) || (sgn == 0 && rnd_mode == BID_ROUNDING_DOWN) {
pres.w[1] = sgn | _LARGEST_BID128_HIGH;
pres.w[0] = _LARGEST_BID128_LOW;
} else {
pres.w[1] = sgn | INFINITY_MASK64;
pres.w[0] = 0;
}
} else {
pres.w[1] = sgn | INFINITY_MASK64;
pres.w[0] = 0;
}
return *pres;
}
}
pres.w[0] = coeff.w[0];
let mut tmp = expon as u64;
tmp <<= 49;
pres.w[1] = sgn | tmp | coeff.w[1];
*pres
}
#[inline(always)]
pub fn bid_handle_uf_128_rem(pres: &mut BidUint128, sgn: BidUint64, expon: i32, mut cq: BidUint128, r: BidUint64, rounding: IdecRound, flags: &mut IdecFlags) -> BidUint128 {
let mut qh: BidUint128 = Default::default();
let mut ql: BidUint128 = Default::default();
let mut qh1: BidUint128 = Default::default();
let mut stemp: BidUint128 = Default::default();
let mut tmp: BidUint128 = Default::default();
let mut tmp1: BidUint128 = Default::default();
let mut cq2: BidUint128 = Default::default();
let mut cq8: BidUint128 = Default::default();
let mut carry: BidUint64;
let cy: BidUint64;
let mut rmode: u32;
let mut status: u32;
if expon + MAX_FORMAT_DIGITS_128 < 0 {
if cfg!(feature = "bid-set-status-flags") {
set_status_flags!(flags, BID_UNDERFLOW_EXCEPTION | BID_INEXACT_EXCEPTION);
}
pres.w[1] = sgn;
pres.w[0] = 0;
if cfg!(not(feature = "ieee-round-nearest-ties-away")) && cfg!(not(feature = "ieee-round-nearest")) {
if (sgn > 0 && rounding == BID_ROUNDING_DOWN) || (sgn == 0 && rounding == BID_ROUNDING_UP) {
pres.w[0] = 1;
}
}
return *pres;
}
cq2.w[1] = (cq.w[1] << 1) | (cq.w[0] >> 63);
cq2.w[0] = cq.w[0] << 1;
cq8.w[1] = (cq.w[1] << 3) | (cq.w[0] >> 61);
cq8.w[0] = cq.w[0] << 3;
add_128_128!(cq, cq2, cq8);
if r > 0 {
cq.w[0] |= 1;
}
let ed2: i32 = 1 - expon;
if cfg!(not(feature = "ieee-round-nearest-ties-away")) {
if cfg!(not(feature = "ieee-round-nearest")) {
rmode = rounding;
if sgn > 0 && rmode.wrapping_sub(1) < 2 {
rmode = 3 - rmode;
}
} else {
rmode = 0;
}
} else {
rmode = 0;
}
let t128: BidUint128 = bid_round_const_table_128![rmode, ed2];
add_carry_out!(cq.w[0], carry, t128.w[0], cq.w[0]);
cq.w[1] = cq.w[1] + t128.w[1] + carry;
let tp128: BidUint128 = bid_reciprocals10_128![ed2];
mul_128x128_full!(qh, ql, cq, tp128);
let amount: i32 = bid_recip_scale![ed2];
if amount >= 64 {
cq.w[0] = qh.w[1] >> (amount - 64);
cq.w[1] = 0;
} else {
shr_128!(cq, qh, amount);
}
if cfg!(not(feature = "ieee-round-nearest-ties-away")) {
let feature_gate = if cfg!(feature = "ieee-round-nearest") { true } else { rounding == 0 };
if feature_gate && (cq.w[0] & 1) > 0 {
shl_128_long!(qh1, qh, (128 - amount));
if qh1.w[1] == 0 && qh1.w[0] == 0 && (ql.w[1] < bid_reciprocals10_128![ed2].w[1] || (ql.w[1] == bid_reciprocals10_128![ed2].w[1] && ql.w[0] < bid_reciprocals10_128![ed2].w[0])) {
dec!(cq.w[0]);
}
}
}
if cfg!(feature = "bid-set-status-flags") {
if is_inexact!(flags) {
set_status_flags!(flags, BID_UNDERFLOW_EXCEPTION);
} else {
status = BID_INEXACT_EXCEPTION;
shl_128_long!(qh1, qh, (128 - amount));
match rmode {
BID_ROUNDING_TO_NEAREST | BID_ROUNDING_TIES_AWAY => {
if qh1.w[1] == 0x8000000000000000 && (qh1.w[0] == 0) && (ql.w[1] < bid_reciprocals10_128![ed2].w[1] || (ql.w[1] == bid_reciprocals10_128![ed2].w[1] && ql.w[0] < bid_reciprocals10_128![ed2].w[0])) {
status = BID_EXACT_STATUS;
}
}
BID_ROUNDING_DOWN | BID_ROUNDING_TO_ZERO => {
if (qh1.w[1] == 0) && (qh1.w[0] == 0) && (ql.w[1] < bid_reciprocals10_128![ed2].w[1] || (ql.w[1] == bid_reciprocals10_128![ed2].w[1] && ql.w[0] < bid_reciprocals10_128![ed2].w[0])) {
status = BID_EXACT_STATUS;
}
}
_ => {
add_carry_out!(stemp.w[0], cy, ql.w[0], bid_reciprocals10_128![ed2].w[0]);
add_carry_in_out!(stemp.w[1], carry, ql.w[1], bid_reciprocals10_128![ed2].w[1], cy);
shr_128_long!(qh, qh1, (128 - amount));
tmp.w[0] = 1;
tmp.w[1] = 0;
shl_128_long!(tmp1, tmp, amount);
inc!(qh.w[0], carry);
if qh.w[0] < carry {
inc!(qh.w[1]);
}
if unsigned_compare_ge_128!(qh, tmp1) {
status = BID_EXACT_STATUS;
}
}
}
if status != BID_EXACT_STATUS {
set_status_flags!(flags, BID_UNDERFLOW_EXCEPTION | status);
}
}
}
pres.w[1] = sgn | cq.w[1];
pres.w[0] = cq.w[0];
*pres
}
#[inline(always)]
pub fn handle_uf_128(pres: &mut BidUint128, sgn: BidUint64, expon: &mut i32, mut cq: BidUint128, rnd_mode: IdecRound, flags: &mut IdecFlags) -> BidUint128 {
let mut stemp: BidUint128 = Default::default();
let mut tmp: BidUint128 = Default::default();
let mut tmp1: BidUint128 = Default::default();
let mut qh: BidUint128 = BidUint128::default();
let mut qh1: BidUint128 = BidUint128::default();
let mut ql: BidUint128 = Default::default();
let mut carry: BidUint64;
let cy: BidUint64;
let rmode: u32;
let mut status: u32;
if *expon + MAX_FORMAT_DIGITS_128 < 0 {
if cfg!(feature = "bid-set-status-flags") {
set_status_flags!(flags, BID_UNDERFLOW_EXCEPTION | BID_INEXACT_EXCEPTION);
}
pres.w[1] = sgn;
pres.w[0] = 0;
if !cfg!(feature = "ieee-round-nearest-ties-away") && !cfg!(feature = "ieee-round-nearest") {
use crate::bid_functions::{BID_ROUNDING_DOWN, BID_ROUNDING_UP};
if (sgn > 0 && rnd_mode == BID_ROUNDING_DOWN) || (sgn == 0 && rnd_mode == BID_ROUNDING_UP) {
pres.w[0] = 1;
}
}
return *pres;
}
let ed2 = 0 - *expon;
if !cfg!(feature = "ieee-round-nearest-ties-away") {
if !cfg!(feature = "ieee-round-nearest") {
rmode = if sgn > 0 && (rnd_mode.wrapping_sub(1)) < 2 { 3 - rnd_mode } else { rnd_mode }
} else {
rmode = 0;
}
} else {
rmode = 0;
}
let t128 = bid_round_const_table_128!(rmode, ed2);
add_carry_out!(cq.w[0], carry, t128.w[0], cq.w[0]);
cq.w[1] = cq.w[1] + t128.w[1] + carry;
let tp128 = bid_reciprocals10_128!(ed2);
mul_128x128_full!(qh, ql, cq, tp128);
let amount = bid_recip_scale!(ed2);
if amount >= 64 {
cq.w[0] = qh.w[1] >> (amount - 64);
cq.w[1] = 0;
} else {
shr_128!(cq, qh, amount);
}
*expon = 0;
if !cfg!(feature = "ieee-round-nearest-ties-away") {
let feature_gate = { if cfg!(feature = "ieee-round-nearest") { true } else { rnd_mode == 0 } };
if feature_gate && cq.w[0] & 1 > 0 {
shl_128_long!(qh1, qh, 128 - amount);
if qh1.w[1] == 0 && qh1.w[0] == 0 && (ql.w[1] < bid_reciprocals10_128!(ed2).w[1] || (ql.w[1] == bid_reciprocals10_128!(ed2).w[1] && ql.w[0] < bid_reciprocals10_128!(ed2).w[0])) {
cq.w[0] -= 1;
}
}
}
if cfg!(feature = "bid-set-status-flags") {
use crate::bid_functions::*;
if is_inexact!(flags) {
set_status_flags!(flags, BID_UNDERFLOW_EXCEPTION);
} else {
status = BID_INEXACT_EXCEPTION;
shl_128_long!(qh1, qh, 128 - amount);
match rmode {
BID_ROUNDING_TO_NEAREST | BID_ROUNDING_TIES_AWAY => {
if qh1.w[1] == 0x8000000000000000 && qh1.w[0] == 0 && (ql.w[1] < bid_reciprocals10_128!(ed2).w[1] || (ql.w[1] == bid_reciprocals10_128!(ed2).w[1] && ql.w[0] < bid_reciprocals10_128!(ed2).w[0])) {
status = BID_EXACT_STATUS;
}
}
BID_ROUNDING_DOWN | BID_ROUNDING_TO_ZERO => {
if (qh1.w[1] == 0) && (qh1.w[0] == 0) && (ql.w[1] < bid_reciprocals10_128!(ed2).w[1] || (ql.w[1] == bid_reciprocals10_128!(ed2).w[1] && ql.w[0] < bid_reciprocals10_128!(ed2).w[0])) {
status = BID_EXACT_STATUS;
}
}
_ => {
add_carry_out!(stemp.w[0], cy, ql.w[0], bid_reciprocals10_128!(ed2).w[0]);
add_carry_in_out!(stemp.w[1], carry, ql.w[1], bid_reciprocals10_128!(ed2).w[1], cy);
shr_128_long!(qh, qh1, 128 - amount);
tmp.w[0] = 1;
tmp.w[1] = 0;
shl_128_long!(tmp1, tmp, amount);
inc!(qh.w[0], carry);
if qh.w[0] < carry {
inc!(qh.w[1], 1);
}
if unsigned_compare_ge_128!(qh, tmp1) {
status = BID_EXACT_STATUS;
}
}
}
if status != BID_EXACT_STATUS {
set_status_flags!(flags, BID_UNDERFLOW_EXCEPTION | status);
}
}
}
pres.w[1] = sgn | cq.w[1];
pres.w[0] = cq.w[0];
*pres
}
const SPECIAL_ENCODING_MASK64: u64 = 0x6000000000000000;
const SINFINITY_MASK64: u64 = 0xf800000000000000;
const EXPONENT_MASK128: i32 = 0x3fff;
const NAN_MASK64: u64 = 0x7c00000000000000;
const SMALL_COEFF_MASK128: u64 = 0x0001ffffffffffff;
#[inline(always)]
pub fn unpack_bid128_value(psign_x: &mut BidUint64, pexponent_x: &mut i32, pcoefficient_x: &mut BidUint128, x: BidUint128) -> BidUint64 {
let mut coeff: BidUint128 = Default::default();
let t33: BidUint128;
let ex: BidUint64;
*psign_x = (x.w[1]) & 0x8000000000000000;
if (x.w[1] & INFINITY_MASK64) >= SPECIAL_ENCODING_MASK64 {
if (x.w[1] & INFINITY_MASK64) < INFINITY_MASK64 {
pcoefficient_x.w[0] = 0;
pcoefficient_x.w[1] = 0;
ex = (x.w[1]) >> 47;
*pexponent_x = (ex as i32) & EXPONENT_MASK128;
return 0;
}
t33 = bid_power10_table_128![33];
pcoefficient_x.w[0] = x.w[0];
pcoefficient_x.w[1] = (x.w[1]) & 0x00003fffffffffff;
if unsigned_compare_ge_128!(*pcoefficient_x, t33)
{
pcoefficient_x.w[1] = (x.w[1]) & 0xfe00000000000000;
pcoefficient_x.w[0] = 0;
} else {
pcoefficient_x.w[1] = (x.w[1]) & 0xfe003fffffffffff;
}
if (x.w[1] & NAN_MASK64) == INFINITY_MASK64 {
pcoefficient_x.w[0] = 0;
pcoefficient_x.w[1] = x.w[1] & SINFINITY_MASK64;
}
*pexponent_x = 0;
return 0; }
coeff.w[0] = x.w[0];
coeff.w[1] = (x.w[1]) & SMALL_COEFF_MASK128;
let t34: BidUint128 = bid_power10_table_128![34];
if unsigned_compare_ge_128!(coeff, t34) {
coeff.w[0] = 0;
coeff.w[1] = 0;
}
pcoefficient_x.w[0] = coeff.w[0];
pcoefficient_x.w[1] = coeff.w[1];
ex = (x.w[1]) >> 49;
*pexponent_x = (ex as i32) & EXPONENT_MASK128;
coeff.w[0] | coeff.w[1]
}
#[repr(C)]
pub union U64Double {
pub u: u64,
pub f: f64,
}
#[repr(C)]
pub union IntDouble {
pub i: u64,
pub d: f64,
}
impl Default for IntDouble {
fn default() -> Self {
Self { i: 0 }
}
}
#[repr(C)]
pub union IntFloat {
pub i: u32,
pub d: f32,
}
impl Default for IntFloat {
fn default() -> Self {
Self { i: 0 }
}
}
macro_rules! bits {
($value:expr) => {
((((unsafe { U64Double { f: $value as f64 }.u } >> 52) as u32) & 0x7ff) - 0x3ff) as i32
};
}
pub(crate) use bits;