use arrow::datatypes::{Decimal32Type, Decimal64Type, Decimal128Type, DecimalType};
use arrow::datatypes::{Decimal256Type, i256};
pub(super) const PI_UPPER_F16: half::f16 = half::f16::from_bits(0x4249);
pub(super) const PI_UPPER_F32: f32 = std::f32::consts::PI.next_up();
pub(super) const PI_UPPER_F64: f64 = std::f64::consts::PI.next_up();
pub(super) const NEGATIVE_PI_LOWER_F16: half::f16 = half::f16::from_bits(0xC249);
pub(super) const NEGATIVE_PI_LOWER_F32: f32 = (-std::f32::consts::PI).next_down();
pub(super) const NEGATIVE_PI_LOWER_F64: f64 = (-std::f64::consts::PI).next_down();
pub(super) const FRAC_PI_2_UPPER_F16: half::f16 = half::f16::from_bits(0x3E49);
pub(super) const FRAC_PI_2_UPPER_F32: f32 = std::f32::consts::FRAC_PI_2.next_up();
pub(super) const FRAC_PI_2_UPPER_F64: f64 = std::f64::consts::FRAC_PI_2.next_up();
pub(super) const NEGATIVE_FRAC_PI_2_LOWER_F16: half::f16 = half::f16::from_bits(0xBE49);
pub(super) const NEGATIVE_FRAC_PI_2_LOWER_F32: f32 =
(-std::f32::consts::FRAC_PI_2).next_down();
pub(super) const NEGATIVE_FRAC_PI_2_LOWER_F64: f64 =
(-std::f64::consts::FRAC_PI_2).next_down();
macro_rules! decimal_ones_lut {
() => {{
let mut values = [1; _];
let mut i = 1;
while i < values.len() {
values[i] = values[i - 1] * 10;
i += 1;
}
values
}};
}
pub(super) const DECIMAL32_ONES: [i32; Decimal32Type::MAX_SCALE as usize] =
decimal_ones_lut!();
pub(super) const DECIMAL64_ONES: [i64; Decimal64Type::MAX_SCALE as usize] =
decimal_ones_lut!();
pub(super) const DECIMAL128_ONES: [i128; Decimal128Type::MAX_SCALE as usize] =
decimal_ones_lut!();
pub(super) const DECIMAL256_ONES: [i256; Decimal256Type::MAX_SCALE as usize] = {
let mut values = [i256::ONE; _];
let mut i = 1;
while i < values.len() {
let (low, high) = values[i - 1].to_parts();
let low_product = (low as u64 as u128) * 10;
let high_product = (low >> 64) * 10 + (low_product >> 64);
let low = ((high_product as u64 as u128) << 64) | low_product as u64 as u128;
let carry = (high_product >> 64) as i128;
values[i] = i256::from_parts(low, high * 10 + carry);
i += 1;
}
values
};
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_ensure_correct_decimal256_ones() {
for (scale, val) in DECIMAL256_ONES.iter().enumerate() {
let zeros = "0".repeat(scale);
let num = "1".to_string() + &zeros;
let num = i256::from_string(&num).unwrap();
assert_eq!(num, *val, "{scale}");
}
}
}