#[inline]
pub const fn encode_i64_sortable(value: i64) -> u64 {
(value as u64) ^ 0x8000_0000_0000_0000
}
#[inline]
pub const fn decode_i64_sortable(sortable: u64) -> i64 {
(sortable ^ 0x8000_0000_0000_0000) as i64
}
#[inline]
pub const fn encode_f64_sortable(value: f64) -> u64 {
let bits = value.to_bits();
if bits & 0x8000_0000_0000_0000 != 0 {
!bits
} else {
bits ^ 0x8000_0000_0000_0000
}
}
#[inline]
pub const fn decode_f64_sortable(sortable: u64) -> f64 {
let bits = if sortable & 0x8000_0000_0000_0000 != 0 {
sortable ^ 0x8000_0000_0000_0000
} else {
!sortable
};
f64::from_bits(bits)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn should_roundtrip_i64_values() {
let values = [
i64::MIN,
i64::MIN + 1,
-1000,
-1,
0,
1,
1000,
i64::MAX - 1,
i64::MAX,
];
for value in values {
let encoded = encode_i64_sortable(value);
let decoded = decode_i64_sortable(encoded);
assert_eq!(decoded, value, "Roundtrip failed for {}", value);
}
}
#[test]
fn should_preserve_i64_ordering() {
let values = [i64::MIN, -1000, -1, 0, 1, 1000, i64::MAX];
for window in values.windows(2) {
let (a, b) = (window[0], window[1]);
let encoded_a = encode_i64_sortable(a);
let encoded_b = encode_i64_sortable(b);
assert!(
encoded_a < encoded_b,
"Ordering violated: {} (0x{:016x}) should be < {} (0x{:016x})",
a,
encoded_a,
b,
encoded_b
);
}
}
#[test]
fn should_roundtrip_f64_values() {
let values = [
f64::NEG_INFINITY,
f64::MIN,
-1000.5,
-1.0,
-f64::MIN_POSITIVE,
-0.0,
0.0,
f64::MIN_POSITIVE,
1.0,
1000.5,
f64::MAX,
f64::INFINITY,
];
for value in values {
let encoded = encode_f64_sortable(value);
let decoded = decode_f64_sortable(encoded);
assert_eq!(
decoded.to_bits(),
value.to_bits(),
"Roundtrip failed for {}",
value
);
}
}
#[test]
fn should_preserve_f64_ordering() {
let values = [
f64::NEG_INFINITY,
f64::MIN,
-1000.5,
-1.0,
-0.0, 0.0,
1.0,
1000.5,
f64::MAX,
f64::INFINITY,
];
for window in values.windows(2) {
let (a, b) = (window[0], window[1]);
if a == b {
continue;
}
let encoded_a = encode_f64_sortable(a);
let encoded_b = encode_f64_sortable(b);
assert!(
encoded_a < encoded_b,
"Ordering violated: {} (0x{:016x}) should be < {} (0x{:016x})",
a,
encoded_a,
b,
encoded_b
);
}
}
#[test]
fn should_handle_f64_special_values() {
let nan = f64::NAN;
let encoded = encode_f64_sortable(nan);
let decoded = decode_f64_sortable(encoded);
assert!(decoded.is_nan());
}
}