use crate::{
decimal::{
dec::{transmute::transmute, ControlBlock},
Decimal, Sign, Context,
},
int::UInt,
};
type D<const N: usize> = Decimal<N>;
const PSI: [u64; 64] = [
1,
2,
4,
8,
16,
32,
64,
128,
256,
512,
1024,
2048,
4096,
8192,
16384,
32768,
65536,
131072,
262144,
524288,
1048576,
2097152,
4194304,
8388608,
16777216,
33554432,
67108864,
134217728,
268435456,
536870912,
1073741824,
2147483648,
4294967296,
8589934592,
17179869184,
34359738368,
68719476736,
137438953472,
274877906944,
549755813888,
1099511627776,
2199023255552,
4398046511104,
8796093022208,
17592186044416,
35184372088832,
70368744177664,
140737488355328,
281474976710656,
562949953421312,
1125899906842624,
2251799813685248,
4503599627370496,
9007199254740992,
18014398509481984,
36028797018963968,
72057594037927936,
144115188075855872,
288230376151711744,
576460752303423488,
1152921504606846976,
2305843009213693952,
4611686018427387904,
9223372036854775808,
];
const D_EXP: [i16; 1075] = [
1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 15, 15, 15, 16, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 19, 19, 20, 20, 20, 21, 21, 21, 22, 22, 22, 22, 23, 23, 23, 24, 24, 24, 25, 25, 25, 25, 26, 26, 26, 27, 27, 27, 28, 28, 28, 28, 29, 29, 29, 30, 30, 30, 31, 31, 31, 32, 32, 32, 32, 33, 33, 33, 34, 34, 34, 35, 35, 35, 35, 36, 36, 36, 37, 37, 37, 38, 38, 38, 38, 39, 39, 39, 40, 40, 40, 41, 41, 41, 41, 42, 42, 42, 43, 43, 43, 44, 44, 44, 44, 45, 45, 45, 46, 46, 46, 47, 47, 47, 47, 48, 48, 48, 49, 49, 49, 50, 50, 50, 50, 51, 51, 51, 52, 52, 52, 53, 53, 53, 53, 54, 54, 54, 55, 55, 55, 56, 56, 56, 56, 57, 57, 57, 58, 58, 58, 59, 59, 59, 60, 60, 60, 60, 61, 61, 61, 62, 62, 62, 63, 63, 63, 63, 64, 64, 64, 65, 65, 65, 66, 66, 66, 66, 67, 67, 67, 68, 68, 68, 69, 69, 69, 69, 70, 70, 70, 71, 71, 71, 72, 72, 72, 72, 73, 73, 73, 74, 74, 74, 75, 75, 75, 75, 76, 76, 76, 77, 77, 77, 78, 78, 78, 78, 79, 79, 79, 80, 80, 80, 81, 81, 81, 81, 82, 82, 82, 83, 83, 83, 84, 84, 84, 84, 85, 85, 85, 86, 86, 86, 87, 87, 87, 87, 88, 88, 88, 89, 89, 89, 90, 90, 90, 91, 91, 91, 91, 92, 92, 92, 93, 93, 93, 94, 94, 94, 94, 95, 95, 95, 96, 96, 96, 97, 97, 97, 97, 98, 98, 98, 99, 99, 99, 100, 100, 100, 100, 101, 101, 101, 102, 102, 102, 103, 103, 103, 103, 104, 104, 104, 105, 105, 105, 106, 106, 106, 106, 107, 107, 107, 108, 108, 108, 109, 109, 109, 109, 110, 110, 110, 111, 111, 111, 112, 112, 112, 112, 113, 113, 113, 114, 114, 114, 115, 115, 115, 115, 116, 116, 116, 117, 117, 117, 118, 118, 118, 119, 119, 119, 119, 120, 120, 120, 121, 121, 121, 122, 122, 122, 122, 123, 123, 123, 124, 124, 124, 125, 125, 125, 125, 126, 126, 126, 127, 127, 127, 128, 128, 128, 128, 129, 129, 129, 130, 130, 130, 131, 131, 131, 131, 132, 132, 132, 133, 133, 133, 134, 134, 134, 134, 135, 135, 135, 136, 136, 136, 137, 137, 137, 137, 138, 138, 138, 139, 139, 139, 140, 140, 140, 140, 141, 141, 141, 142, 142, 142, 143, 143, 143, 143, 144, 144, 144, 145, 145, 145, 146, 146, 146, 146, 147, 147, 147, 148, 148, 148, 149, 149, 149, 150, 150, 150, 150, 151, 151, 151, 152, 152, 152, 153, 153, 153, 153, 154, 154, 154, 155, 155, 155, 156, 156, 156, 156, 157, 157, 157, 158, 158, 158, 159, 159, 159, 159, 160, 160, 160, 161, 161, 161, 162, 162, 162, 162, 163, 163, 163, 164, 164, 164, 165, 165, 165, 165, 166, 166, 166, 167, 167, 167, 168, 168, 168, 168, 169, 169, 169, 170, 170, 170, 171, 171, 171, 171, 172, 172, 172, 173, 173, 173, 174, 174, 174, 174, 175, 175, 175, 176, 176, 176, 177, 177, 177, 178, 178, 178, 178, 179, 179, 179, 180, 180, 180, 181, 181, 181, 181, 182, 182, 182, 183, 183, 183, 184, 184, 184, 184, 185, 185, 185, 186, 186, 186, 187, 187, 187, 187, 188, 188, 188, 189, 189, 189, 190, 190, 190, 190, 191, 191, 191, 192, 192, 192, 193, 193, 193, 193, 194, 194, 194, 195, 195, 195, 196, 196, 196, 196, 197, 197, 197, 198, 198, 198, 199, 199, 199, 199, 200, 200, 200, 201, 201, 201, 202, 202, 202, 202, 203, 203, 203, 204, 204, 204, 205, 205, 205, 206, 206, 206, 206, 207, 207, 207, 208, 208, 208, 209, 209, 209, 209, 210, 210, 210, 211, 211, 211, 212, 212, 212, 212, 213, 213, 213, 214, 214, 214, 215, 215, 215, 215, 216, 216, 216, 217, 217, 217, 218, 218, 218, 218, 219, 219, 219, 220, 220, 220, 221, 221, 221, 221, 222, 222, 222, 223, 223, 223, 224, 224, 224, 224, 225, 225, 225, 226, 226, 226, 227, 227, 227, 227, 228, 228, 228, 229, 229, 229, 230, 230, 230, 230, 231, 231, 231, 232, 232, 232, 233, 233, 233, 233, 234, 234, 234, 235, 235, 235, 236, 236, 236, 237, 237, 237, 237, 238, 238, 238, 239, 239, 239, 240, 240, 240, 240, 241, 241, 241, 242, 242, 242, 243, 243, 243, 243, 244, 244, 244, 245, 245, 245, 246, 246, 246, 246, 247, 247, 247, 248, 248, 248, 249, 249, 249, 249, 250, 250, 250, 251, 251, 251, 252, 252, 252, 252, 253, 253, 253, 254, 254, 254, 255, 255, 255, 255, 256, 256, 256, 257, 257, 257, 258, 258, 258, 258, 259, 259, 259, 260, 260, 260, 261, 261, 261, 261, 262, 262, 262, 263, 263, 263, 264, 264, 264, 265, 265, 265, 265, 266, 266, 266, 267, 267, 267, 268, 268, 268, 268, 269, 269, 269, 270, 270, 270, 271, 271, 271, 271, 272, 272, 272, 273, 273, 273, 274, 274, 274, 274, 275, 275, 275, 276, 276, 276, 277, 277, 277, 277, 278, 278, 278, 279, 279, 279, 280, 280, 280, 280, 281, 281, 281, 282, 282, 282, 283, 283, 283, 283, 284, 284, 284, 285, 285, 285, 286, 286, 286, 286, 287, 287, 287, 288, 288, 288, 289, 289, 289, 289, 290, 290, 290, 291, 291, 291, 292, 292, 292, 292, 293, 293, 293, 294, 294, 294, 295, 295, 295, 296, 296, 296, 296, 297, 297, 297, 298, 298, 298, 299, 299, 299, 299, 300, 300, 300, 301, 301, 301, 302, 302, 302, 302, 303, 303, 303, 304, 304, 304, 305, 305, 305, 305, 306, 306, 306, 307, 307, 307, 308, 308, 308, 308, 309, 309, 309, 310, 310, 310, 311, 311, 311, 311, 312, 312, 312, 313, 313, 313, 314, 314, 314, 314, 315, 315, 315, 316, 316, 316, 317, 317, 317, 317, 318, 318, 318, 319, 319, 319, 320, 320, 320, 320, 321, 321, 321, 322, 322, 322, 323, 323, 323, 324, 324, ];
#[inline]
pub(crate) const fn lookup<const N: usize>(b_exp: i16) -> (i16, D<N>) {
debug_assert!(b_exp >= 0 && b_exp <= 1074);
let d_exp = D_EXP[b_exp as usize];
let psi = if b_exp < 64 {
transmute(D::<1>::new(
UInt::from_digits([PSI[b_exp as usize]]),
ControlBlock::basic(d_exp, Sign::Plus),
Context::DEFAULT,
))
} else if b_exp < 128 {
transmute(D::<2>::new(
UInt::from_digits([0, PSI[b_exp as usize - 64]]),
ControlBlock::basic(d_exp, Sign::Plus),
Context::DEFAULT,
))
} else if b_exp < 192 {
transmute(D::<3>::new(
UInt::from_digits([0, 0, PSI[b_exp as usize - 128]]),
ControlBlock::basic(d_exp, Sign::Plus),
Context::DEFAULT,
))
} else if b_exp < 256 {
transmute(D::<4>::new(
UInt::from_digits([0, 0, 0, PSI[b_exp as usize - 192]]),
ControlBlock::basic(d_exp, Sign::Plus),
Context::DEFAULT,
))
} else if b_exp < 320 {
transmute(D::<5>::new(
UInt::from_digits([0, 0, 0, 0, PSI[b_exp as usize - 256]]),
ControlBlock::basic(d_exp, Sign::Plus),
Context::DEFAULT,
))
} else if b_exp < 384 {
transmute(D::<6>::new(
UInt::from_digits([0, 0, 0, 0, 0, PSI[b_exp as usize - 320]]),
ControlBlock::basic(d_exp, Sign::Plus),
Context::DEFAULT,
))
} else if b_exp < 448 {
transmute(D::<7>::new(
UInt::from_digits([0, 0, 0, 0, 0, 0, PSI[b_exp as usize - 384]]),
ControlBlock::basic(d_exp, Sign::Plus),
Context::DEFAULT,
))
} else if b_exp < 512 {
transmute(D::<8>::new(
UInt::from_digits([0, 0, 0, 0, 0, 0, 0, PSI[b_exp as usize - 448]]),
ControlBlock::basic(d_exp, Sign::Plus),
Context::DEFAULT,
))
} else if b_exp < 576 {
transmute(D::<9>::new(
UInt::from_digits([0, 0, 0, 0, 0, 0, 0, 0, PSI[b_exp as usize - 512]]),
ControlBlock::basic(d_exp, Sign::Plus),
Context::DEFAULT,
))
} else if b_exp < 640 {
transmute(D::<10>::new(
UInt::from_digits([0, 0, 0, 0, 0, 0, 0, 0, 0, PSI[b_exp as usize - 576]]),
ControlBlock::basic(d_exp, Sign::Plus),
Context::DEFAULT,
))
} else if b_exp < 704 {
transmute(D::<11>::new(
UInt::from_digits([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, PSI[b_exp as usize - 640]]),
ControlBlock::basic(d_exp, Sign::Plus),
Context::DEFAULT,
))
} else if b_exp < 768 {
transmute(D::<12>::new(
UInt::from_digits([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, PSI[b_exp as usize - 704]]),
ControlBlock::basic(d_exp, Sign::Plus),
Context::DEFAULT,
))
} else if b_exp < 832 {
transmute(D::<13>::new(
UInt::from_digits([
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
PSI[b_exp as usize - 768],
]),
ControlBlock::basic(d_exp, Sign::Plus),
Context::DEFAULT,
))
} else if b_exp < 896 {
transmute(D::<14>::new(
UInt::from_digits([
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
PSI[b_exp as usize - 832],
]),
ControlBlock::basic(d_exp, Sign::Plus),
Context::DEFAULT,
))
} else if b_exp < 960 {
transmute(D::<15>::new(
UInt::from_digits([
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
PSI[b_exp as usize - 896],
]),
ControlBlock::basic(d_exp, Sign::Plus),
Context::DEFAULT,
))
} else if b_exp < 1024 {
transmute(D::<16>::new(
UInt::from_digits([
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
PSI[b_exp as usize - 960],
]),
ControlBlock::basic(d_exp, Sign::Plus),
Context::DEFAULT,
))
} else {
transmute(D::<17>::new(
UInt::from_digits([
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
PSI[b_exp as usize - 1024],
]),
ControlBlock::basic(d_exp, Sign::Plus),
Context::DEFAULT,
))
};
(d_exp, psi)
}