use std::cmp::Ordering;
use std::convert::TryInto;
use crate::compressor::Compressor;
use crate::decompressor::Decompressor;
use crate::types::{DataType, NumberLike};
const SIGN_BIT_MASK: u64 = 1_u64 << 63;
impl NumberLike for f64 {
fn num_eq(&self, other: &f64) -> bool {
self.to_bits() == other.to_bits()
}
fn num_cmp(&self, other: &f64) -> Ordering {
F64DataType::f64_to_u64(*self).cmp(&F64DataType::f64_to_u64(*other))
}
type DT = F64DataType;
}
pub struct F64DataType {}
impl F64DataType {
fn f64_to_u64(x: f64) -> u64 {
let mem_layout_x_u64 = x.to_bits();
if mem_layout_x_u64 & SIGN_BIT_MASK > 0 {
!mem_layout_x_u64
} else {
mem_layout_x_u64 ^ SIGN_BIT_MASK
}
}
fn from_u64(x: u64) -> f64 {
if x & SIGN_BIT_MASK > 0 {
f64::from_bits(x ^ SIGN_BIT_MASK)
} else {
f64::from_bits(!x)
}
}
}
impl DataType<f64> for F64DataType {
const HEADER_BYTE: u8 = 5;
const BIT_SIZE: usize = 64;
fn offset_diff(upper: f64, lower: f64) -> u64 {
Self::f64_to_u64(upper) - Self::f64_to_u64(lower)
}
fn add_offset(lower: f64, off: u64) -> f64 {
Self::from_u64(Self::f64_to_u64(lower) + off)
}
fn bytes_from(num: f64) -> Vec<u8> {
num.to_be_bytes().to_vec()
}
fn from_bytes(bytes: Vec<u8>) -> f64 {
f64::from_be_bytes(bytes.try_into().unwrap())
}
}
pub type F64Compressor = Compressor<i64>;
pub type F64Decompressor = Decompressor<i64>;