// Copyright 2026 Noverberrain.
// SPDX-License-Identifier: Apache-2.0
///|
/// The original binary precision, without decimal rounding or widening FLOAT.
pub(all) enum FloatingValue {
Single(Float)
DoublePrecision(Double)
} derive(Debug, Eq)
///|
pub extend FloatingValue with Eq::{equal, not_equal}
///|
pub extend FloatingValue with @debug.Debug::{to_repr}
///|
/// A finite value, its raw IEEE bits (low 32 for FLOAT), and bytes consumed.
/// Bits preserve negative zero independently of numeric equality or printing.
pub struct DecodedFloating {
value : FloatingValue
bits : UInt64
bytes_read : Int32
} derive(Debug, Eq)
///|
pub extend DecodedFloating with Eq::{equal, not_equal}
///|
pub extend DecodedFloating with @debug.Debug::{to_repr}
///|
/// Decode a present, non-NULL FLOAT (4) or DOUBLE (5), little-endian IEEE 754.
/// Require a one-byte metadata width of 4 or 8 respectively; reject NaN/Inf
/// with raw bits in the error. Preserve signed zero and finite subnormals.
/// `file_offset` locates this field's first byte; `column_index` is zero-based.
/// No UNSIGNED schema constraint, SQL rounding or NULL bitmap is inferred.
/// Trailing input is untouched; bytes_read is 4 or 8.
pub fn TableColumn::decode_floating(
self : TableColumn,
data : BytesView,
file_offset~ : UInt64,
column_index~ : Int32,
) -> DecodedFloating raise DecodeError {
let width = match self.wire_type {
4 => 4
5 => 8
wire_type =>
raise UnsupportedFloatingColumn(file_offset~, column_index~, wire_type~)
}
guard self.metadata.length() == 1 && self.metadata[0].to_int() == width else {
raise InvalidFloatingMetadata(
file_offset~,
column_index~,
expected_width=width,
)
}
guard data.length() >= width else {
raise TruncatedColumnValue(
file_offset~,
column_index~,
expected=width,
actual=data.length(),
)
}
let mut bits = 0UL
for i in 0..