pub struct Float(/* private fields */);Expand description
A floating-point value stored in its shortest CBOR encoding form.
Internally the raw bits are stored as f16, f32, or f64: whichever is the
shortest form that preserves the value exactly (including NaN payloads
and the sign of zero). CBOR::Core’s deterministic encoding rules require
this “shortest form” selection, so a Float mirrors the bytes that will
be written on the wire.
Two Float values are equal iff they encode to the same CBOR bytes.
This differs from IEEE 754 equality in two ways:
Float(+0.0) != Float(-0.0)because they encode to different CBOR bytes.- Two NaNs compare equal if and only if they have identical payloads and sign, since that determines the encoding.
§Construction
Float::newfor floats and integers.Float::with_payloadfor non-finite values with a given payload.
§Examples
use cbor_core::Float;
// Shortest-form storage: 1.0 fits in f16.
assert_eq!(Float::new(1.0_f64).data_type(), cbor_core::DataType::Float16);
// Non-finite round-trip via payload.
let nan = Float::with_payload(1);
assert!(nan.to_f64().is_nan());
assert_eq!(nan.to_payload(), Ok(1));Implementations§
Source§impl Float
impl Float
Sourcepub fn new(value: impl Into<Self>) -> Self
pub fn new(value: impl Into<Self>) -> Self
Create a floating-point value in shortest CBOR form.
Equivalent to Float::from(value). The constructor chooses the
narrowest CBOR::Core deterministic encoding width that represents
value exactly.
Accepted input types: f32, f64, u8, u16, u32, i8, i16, i32,
bool (false becomes 0.0, true becomes 1.0).
64-bit integers are intentionally rejected because they are not
losslessly representable as f64 in general.
§Examples
use cbor_core::{DataType, Float};
assert_eq!(Float::new(0.0_f64).data_type(), DataType::Float16);
assert_eq!(Float::new(true).to_f64(), 1.0);Sourcepub const fn with_payload(payload: u64) -> Self
pub const fn with_payload(payload: u64) -> Self
Create a non-finite floating-point value from a payload.
The payload is a 53-bit integer, laid out as described in section
2.3.4.2 of draft-rundgren-cbor-core-25. Bit 52 becomes the sign bit
of the resulting float, while bits 51-0 form the significand in
reversed order.
Bit reversal keeps a given bit position invariant across the f16, f32, and f64 encodings: bit 0 of the payload is always the most-significant significand bit. The result is stored in the shortest CBOR form that preserves the payload.
| Payload | CBOR encoding | Diagnostic notation |
|---|---|---|
0 | [0xf9, 0x7c 0x00] | Infinity |
0x01 | [0xf9, 0x7e 0x00] | NaN |
0x10_0000_0000_0000 | [0xf9, 0xfc 0x00] | -Infinity |
The maximum allowed payload is 0x1f_ffff_ffff_ffff (53 bits).
§Panics
Panics if payload exceeds the 53-bit maximum.
§Examples
use cbor_core::Float;
assert!(Float::with_payload(0).to_f64().is_infinite());
assert!(Float::with_payload(1).to_f64().is_nan());
assert_eq!(Float::with_payload(2).to_payload(), Ok(2));Sourcepub const fn from_f64(value: f64) -> Self
pub const fn from_f64(value: f64) -> Self
Create a Float from an f64, usable in const context.
const counterpart of Float::from(value) / Float::new. The
value is reduced to the shortest CBOR form (f16, f32, or f64) that
preserves it bit-exactly, including NaN payloads and the sign of
zero.
use cbor_core::Float;
const F: Float = Float::from_f64(1.0);
assert_eq!(F.to_f64(), 1.0);Sourcepub const fn from_f32(value: f32) -> Self
pub const fn from_f32(value: f32) -> Self
Create a Float from an f32, usable in const context.
const counterpart of Float::from(value) / Float::new for
f32 inputs. NaN payloads are widened without hardware
canonicalization; the result is then stored in the shortest CBOR
form that preserves the value.
use cbor_core::Float;
const F: Float = Float::from_f32(1.0);
assert_eq!(F.to_f32(), Ok(1.0));Sourcepub const fn data_type(&self) -> DataType
pub const fn data_type(&self) -> DataType
Return the DataType indicating the storage width (f16, f32, or f64).
use cbor_core::{Float, DataType};
assert_eq!(Float::new(1.5).data_type(), DataType::Float16);
assert_eq!(Float::new(1.00048828125).data_type(), DataType::Float32);
assert_eq!(Float::new(1.1).data_type(), DataType::Float64);Sourcepub const fn to_f64(self) -> f64
pub const fn to_f64(self) -> f64
Widen to f64, preserving the exact bit pattern.
Finite values widen losslessly. For NaN values the payload bits are copied verbatim (without hardware canonicalization).
Sourcepub const fn to_f32(self) -> Result<f32>
pub const fn to_f32(self) -> Result<f32>
Narrow to f32 when the value fits exactly.
Returns Err(Error::Precision) when the underlying storage is f64,
since f64 values cannot in general be narrowed without loss. f16 and
f32 values convert losslessly; NaN payloads are preserved.
Sourcepub const fn to_payload(self) -> Result<u64>
pub const fn to_payload(self) -> Result<u64>
Retrieve the 53-bit payload of a non-finite value.
Returns Err(Error::InvalidValue) for finite
floats. For non-finite values, the payload is reconstructed from the
underlying f16/f32/f64 bits by the inverse of Float::with_payload.
use cbor_core::{Float, Error};
for payload in [0, 1, 2, 0x400, 0x1fffffffffffff] {
assert_eq!(Float::with_payload(payload).to_payload(), Ok(payload));
}
assert_eq!(Float::new(1.0).to_payload(), Err(Error::InvalidValue));