### Example Function Signature with Typed Floats Source: https://github.com/tdelmas/typed_floats/blob/main/README.md Demonstrates how to use a strictly positive finite float type as a parameter and return a strictly positive float. This enforces constraints at compile time, simplifying implementation and usage. ```rust fn fast_inv_sqrt(x: StrictlyPositiveFinite) -> StrictlyPositive; ``` -------------------------------- ### Serde Serialization and Deserialization in Rust Source: https://context7.com/tdelmas/typed_floats/llms.txt Demonstrates how to enable and use `serde` for typed floats. Serialization is transparent, while deserialization validates constraints and returns descriptive errors. ```toml # Cargo.toml [dependencies] typed_floats = { version = "1", features = ["serde"] } ``` ```rust use typed_floats::* use serde::Serialize; // Serialize — transparent, outputs the raw number let a: Positive = 3.0f64.try_into().unwrap(); let json = serde_json::to_string(&a).unwrap(); assert_eq!(json, "3.0"); // Deserialize — validates the constraint let b: Positive = serde_json::from_str("3.0").unwrap(); assert_eq!(b, 3.0f64); // Invalid value returns descriptive error let err: Result, _> = serde_json::from_str("-3.0"); assert!(err.is_err()); assert_eq!(err.unwrap_err().to_string(), "Number is negative at line 1 column 4"); // Use in structs — fully compatible with #[derive(Serialize, Deserialize)] #[derive(Serialize)] struct Measurement { temperature: NonNaN, pressure: StrictlyPositiveFinite, } let m = Measurement { temperature: NonNaN::new(-10.5).unwrap(), pressure: StrictlyPositiveFinite::new(101.325).unwrap(), }; let json = serde_json::to_value(&m).unwrap(); assert_eq!(json["temperature"], -10.5); assert_eq!(json["pressure"], 101.325); ``` -------------------------------- ### Cargo.toml for typed_floats Source: https://context7.com/tdelmas/typed_floats/llms.txt Minimal no_std build with f64, serde, and libm math. Standard build with serde. Maximum safety build with `ensure_no_undefined_behavior`. ```toml # Cargo.toml — minimal no_std build with only f64, serde, and libm math [dependencies] typed_floats = { version = "1", default-features = false, features = ["f64", "serde", "libm"] } # Standard build with serde [dependencies] typed_floats = { version = "1", features = ["serde"] } # Maximum safety (panics instead of UB in release mode) [dependencies] typed_floats = { version = "1", features = ["ensure_no_undefined_behavior"] } ``` -------------------------------- ### Zero Detection Utilities in tf64 Source: https://context7.com/tdelmas/typed_floats/llms.txt Provides free functions for distinguishing +0.0 from -0.0 on raw f64 primitives, and instance methods on typed floats. Note that +0.0 == -0.0 is preserved per IEEE 754. ```rust use typed_floats::tf64; // Free functions on raw f64 assert_eq!(tf64::is_positive_zero(0.0), true); assert_eq!(tf64::is_positive_zero(-0.0), false); assert_eq!(tf64::is_positive_zero(3.0), false); assert_eq!(tf64::is_negative_zero(-0.0), true); assert_eq!(tf64::is_negative_zero(0.0), false); assert_eq!(tf64::is_negative_zero(-1.0), false); // Instance methods on any typed float use typed_floats::NonNaN; let pos_zero: NonNaN = 0.0f64.try_into().unwrap(); let neg_zero: NonNaN = (-0.0f64).try_into().unwrap(); assert_eq!(pos_zero.is_positive_zero(), true); assert_eq!(pos_zero.is_negative_zero(), false); assert_eq!(neg_zero.is_positive_zero(), false); assert_eq!(neg_zero.is_negative_zero(), true); // +0.0 == -0.0 per IEEE 754 (this is preserved, not fixed) assert_eq!(pos_zero, neg_zero); ``` -------------------------------- ### Ordering and Equality with Typed Floats Source: https://context7.com/tdelmas/typed_floats/llms.txt Shows how typed floats implement `Ord`, `Eq`, `PartialOrd`, and `PartialEq`, enabling their use in sorted collections like `BTreeSet`. Cross-type comparisons with raw `f64`/`f32` are also demonstrated. ```Rust use typed_floats::*; use std::collections::BTreeSet; // Ord and Eq allow use in sorted collections let mut set: BTreeSet = BTreeSet::new(); set.insert(3.0f64.try_into().unwrap()); set.insert(1.0f64.try_into().unwrap()); set.insert(2.0f64.try_into().unwrap()); let sorted: Vec = set.iter().map(|x| x.get()).collect(); assert_eq!(sorted, vec![1.0, 2.0, 3.0]); // Cross-type comparisons with f64 let a: f64 = 1.0; let b: StrictlyPositive = 1.0f64.try_into().unwrap(); let c: StrictlyPositiveFinite = 1.0f64.try_into().unwrap(); assert_eq!(a, b); assert_eq!(b, a); assert_eq!(b, c); ``` -------------------------------- ### Typed Float Type Conversions and Error Handling Source: https://context7.com/tdelmas/typed_floats/llms.txt Demonstrates how to create instances of various typed float types using `try_into` and how invalid conversions result in `InvalidNumber` errors. This is useful for validating user input or external data. ```rust use typed_floats::*; // Using tf64 module aliases (equivalent to Type) use typed_floats::tf64; // Each type accepts only valid values for its constraint let a: StrictlyPositiveFinite = 3.14f64.try_into().unwrap(); let b: NegativeFinite = (-2.5f64).try_into().unwrap(); let c: NonNaN = 0.0f64.try_into().unwrap(); let d: tf64::Positive = 0.0f64.try_into().unwrap(); // alias form // Invalid conversions produce typed errors let err: Result = 0.0f64.try_into(); assert_eq!(err, Err(InvalidNumber::Zero)); let nan_err: Result = f64::NAN.try_into(); assert_eq!(nan_err, Err(InvalidNumber::NaN)); let inf_err: Result = f64::INFINITY.try_into(); assert_eq!(inf_err, Err(InvalidNumber::Infinite)); let neg_err: Result = (-1.0f64).try_into(); assert_eq!(neg_err, Err(InvalidNumber::Negative)); ``` -------------------------------- ### Conversions from Integer Types in Rust Source: https://context7.com/tdelmas/typed_floats/llms.txt Demonstrates infallible `From` conversions from `NonZero` integers and fallible `TryFrom` conversions from regular integers. Conversions from `u128`/`i128` are not supported. ```rust use typed_floats::* use core::num::{NonZeroU64, NonZeroI32}; // From NonZero integers — infallible (result is always strictly positive/negative) let a = NonZeroU64::new(42).unwrap(); let b: StrictlyPositive = a.into(); // no try_into needed assert_eq!(b, 42.0); let c = NonZeroI32::new(-5).unwrap(); let d: StrictlyNegative = c.into(); assert_eq!(d, -5.0); // From regular integers — fallible (zero would violate NonZero constraints) let e: Result = i32::try_into(0i32); assert!(e.is_err()); let f: NonNaNFinite = i32::try_into(100i32).map(|x: NonNaNFinite| x).unwrap_or( 100i32.try_into().unwrap() ); assert_eq!(f, 100.0); ``` -------------------------------- ### Typed Float Construction Methods Source: https://context7.com/tdelmas/typed_floats/llms.txt Illustrates different ways to construct typed floats: `new` for checked construction, `unsafe new_unchecked` for performance when validity is guaranteed, and `try_into` for idiomatic Rust conversions. The `?` operator can be used with `try_into` for early returns on errors. ```rust use typed_floats::tf64::{NonNaN, StrictlyPositiveFinite}; use typed_floats::InvalidNumber; // Checked construction — preferred for user input or external data let x = NonNaN::new(3.0).unwrap(); assert_eq!(x.get(), 3.0); let err = NonNaN::new(f64::NAN); assert_eq!(err, Err(InvalidNumber::NaN)); // try_into / TryFrom — idiomatic Rust conversions let y: StrictlyPositiveFinite = 2.5f64.try_into().unwrap(); assert_eq!(y.get(), 2.5); // Unsafe unchecked — zero overhead, caller guarantees validity // Panics in debug mode if value is invalid; UB in release if violated let z = unsafe { StrictlyPositiveFinite::new_unchecked(1.0) }; assert_eq!(z.get(), 1.0); // Early-return pattern using the ? operator fn compute(a: f64, b: f64) -> Result { use typed_floats::*; let a: StrictlyPositiveFinite = a.try_into()?; let b: StrictlyPositiveFinite = b.try_into()?; Ok(a % b) // result type is inferred as PositiveFinite } assert_eq!(compute(5.0, 3.0).unwrap().get(), 2.0); assert_eq!(compute(-1.0, 3.0), Err(InvalidNumber::Negative)); ``` -------------------------------- ### Inspection Methods for Typed Floats Source: https://context7.com/tdelmas/typed_floats/llms.txt Demonstrates the use of compile-time optimized inspection predicates like `is_nan`, `is_infinite`, and `is_finite` for typed floats. For constrained types, these methods compile to constants, while for others like `NonNaN`, they perform runtime checks. ```Rust use typed_floats::tf64::{NonNaN, StrictlyPositiveFinite}; let x: StrictlyPositiveFinite = 3.0f64.try_into().unwrap(); // Statically known — compile-time constants for constrained types assert_eq!(x.is_nan(), false); // always false assert_eq!(x.is_infinite(), false); // always false (finite type) assert_eq!(x.is_finite(), true); // always true assert_eq!(x.is_sign_positive(), true); // always true assert_eq!(x.is_sign_negative(), false); // always false assert_eq!(x.is_positive_zero(), false); // always false (strictly positive) assert_eq!(x.is_negative_zero(), false); // always false // For NonNaN, infiniteness is runtime-checked let y: NonNaN = f64::INFINITY.try_into().unwrap(); assert_eq!(y.is_infinite(), true); assert_eq!(y.is_finite(), false); let z: NonNaN = (-0.0f64).try_into().unwrap(); assert_eq!(z.is_negative_zero(), true); assert_eq!(z.is_positive_zero(), false); ``` -------------------------------- ### Hashing with Typed Floats Source: https://context7.com/tdelmas/typed_floats/llms.txt Illustrates the implementation of the `Hash` trait for typed floats, ensuring consistency with `Eq` for use in hash-based collections like `HashMap` and `HashSet`. It highlights that `+0.0` and `-0.0` hash identically. ```Rust use typed_floats::*; use std::collections::HashMap; // Use typed floats as hash map keys let mut map: HashMap = HashMap::new(); map.insert(1.0f64.try_into().unwrap(), "one"); map.insert(2.0f64.try_into().unwrap(), "two"); let key: NonNaN = 1.0f64.try_into().unwrap(); assert_eq!(map[&key], "one"); // +0.0 and -0.0 hash the same (they are equal) use std::collections::HashSet; let mut set: HashSet = HashSet::new(); set.insert(0.0f64.try_into().unwrap()); // +0.0 set.insert((-0.0f64).try_into().unwrap()); // -0.0 assert_eq!(set.len(), 1); // deduplicated ``` -------------------------------- ### Arithmetic Operations with Typed Floats Source: https://context7.com/tdelmas/typed_floats/llms.txt Demonstrates arithmetic operations like subtraction and addition with typed floats. Compound assignment operators are shown to compile only when the result is guaranteed to fit the left-hand side type. ```Rust use typed_floats::*; let pos_fin: StrictlyPositiveFinite = 1.0f64.try_into().unwrap(); let neg_fin: StrictlyNegativeFinite = (-1.0f64).try_into().unwrap(); // Subtraction of a negative from a positive → StrictlyPositive (may be infinite) let c: StrictlyPositive = pos_fin - neg_fin; assert_eq!(c, 2.0); // Addition of strictly positive and strictly negative → NonNaNFinite let d: NonNaNFinite = pos_fin + neg_fin; assert_eq!(d, 0.0); // Compound assignment only compiles when safe let mut a: StrictlyPositive = f64::MAX.try_into().unwrap(); let b: StrictlyPositive = f64::MAX.try_into().unwrap(); a += b; // OK: StrictlyPositive can hold infinity assert_eq!(a, f64::INFINITY); // This would NOT compile — result could be infinity, violating StrictlyPositiveFinite: // let mut x: StrictlyPositiveFinite = f64::MAX.try_into().unwrap(); // x += x; // compile error ``` -------------------------------- ### Retrieving Underlying Float Value Source: https://context7.com/tdelmas/typed_floats/llms.txt Shows how to extract the primitive `f64` or `f32` value from a typed float using the `.get()` method or by leveraging the `Into` / `Into` trait implementation. These methods provide zero-cost extraction. ```rust use typed_floats::tf64::StrictlyPositiveFinite; let x: StrictlyPositiveFinite = 42.0f64.try_into().unwrap(); // .get() returns the inner f64 let raw: f64 = x.get(); assert_eq!(raw, 42.0); // Into is also implemented let raw2: f64 = x.into(); assert_eq!(raw2, 42.0); ``` -------------------------------- ### Parsing Typed Floats from Strings in Rust Source: https://context7.com/tdelmas/typed_floats/llms.txt Shows how to use the `FromStr` trait for parsing typed floats from strings. Handles `FromStrError` which can wrap `ParseFloatError` or `InvalidNumber` if the constraint is violated. ```rust use typed_floats::* use typed_floats::tf64::StrictlyPositiveFinite; // Successful parse let x: StrictlyPositiveFinite = "3.14".parse().unwrap(); assert_eq!(x.get(), 3.14); // Fails because -1.0 violates StrictlyPositiveFinite let err: Result = "-1.0".parse(); assert!(err.is_err()); assert_eq!(err.unwrap_err().to_string(), "Number is negative"); // Fails because "abc" is not a valid float let parse_err: Result = "abc".parse(); assert!(parse_err.is_err()); // Works for f32 variants too let y: NonNaN = "2.5".parse().unwrap(); assert_eq!(y.get(), 2.5f32); ``` -------------------------------- ### Typed Constants in tf64::consts Source: https://context7.com/tdelmas/typed_floats/llms.txt Uses pre-typed constants for mathematical, boundary, and special float values. NAN is intentionally absent. Ensure appropriate types are used for each constant. ```rust use typed_floats::tf64; use typed_floats::tf64::consts; // Special float boundary constants — typed appropriately let _: tf64::StrictlyPositive = tf64::INFINITY; let _: tf64::StrictlyNegative = tf64::NEG_INFINITY; let _: tf64::PositiveFinite = tf64::ZERO; let _: tf64::NegativeFinite = tf64::NEG_ZERO; let _: tf64::StrictlyPositiveFinite = tf64::MAX; let _: tf64::StrictlyNegativeFinite = tf64::MIN; let _: tf64::StrictlyPositiveFinite = tf64::MIN_POSITIVE; // Subnormal boundary constants let _: tf64::StrictlyPositiveFinite = tf64::MIN_SUBNORMAL_POSITIVE; let _: tf64::StrictlyPositiveFinite = tf64::MAX_SUBNORMAL_POSITIVE; let _: tf64::StrictlyNegativeFinite = tf64::MIN_SUBNORMAL_NEGATIVE; // Mathematical constants — all typed as StrictlyPositiveFinite let pi: tf64::StrictlyPositiveFinite = consts::PI; let tau: tf64::StrictlyPositiveFinite = consts::TAU; let e: tf64::StrictlyPositiveFinite = consts::E; let sqrt2: tf64::StrictlyPositiveFinite = consts::SQRT_2; let ln2: tf64::StrictlyPositiveFinite = consts::LN_2; assert!((pi.get() - std::f64::consts::PI).abs() < f64::EPSILON); ``` -------------------------------- ### Two-Argument Traits for Typed Floats in Rust Source: https://context7.com/tdelmas/typed_floats/llms.txt Illustrates custom traits like `Hypot`, `Min`, `Max`, `Copysign`, `DivEuclid`, `Atan2`, and `Midpoint` for operations involving two typed floats. The return type is the strictest valid type derived from both operands. ```rust use typed_floats::* // hypot — result type depends on both operands let x: NonNaN = 3.0f64.try_into().unwrap(); let y: NonNaN = 4.0f64.try_into().unwrap(); assert_eq!(x.hypot(y), 5.0); // min / max let a: NonNaN = 3.0f64.try_into().unwrap(); let b: NonNaN = 4.0f64.try_into().unwrap(); assert_eq!(Min::min(a, b), 3.0); assert_eq!(Max::max(a, b), 4.0); // copysign — copy sign of rhs onto magnitude of self let mag: NonNaN = 3.5f64.try_into().unwrap(); let neg_sign: NonNaN = (-1.0f64).try_into().unwrap(); let pos_sign: NonNaN = 1.0f64.try_into().unwrap(); assert_eq!(mag.copysign(neg_sign), -3.5); assert_eq!(mag.copysign(pos_sign), 3.5); // div_euclid let dividend: NonNaN = 7.0f64.try_into().unwrap(); let divisor: NonNaN = 4.0f64.try_into().unwrap(); assert_eq!(dividend.div_euclid(divisor), 1.0); assert_eq!((-dividend).div_euclid(divisor), -2.0); // atan2 use typed_floats::tf64::NonNaN as NonNaN64; let y2: NonNaN64 = (-3.0f64).try_into().unwrap(); let x2: NonNaN64 = 3.0f64.try_into().unwrap(); // -π/4 radians let angle = y2.atan2(x2); assert!((angle.get() - (-core::f64::consts::FRAC_PI_4)).abs() < 1e-10); // midpoint let lo: StrictlyPositiveFinite = 1.0f64.try_into().unwrap(); let hi: StrictlyPositiveFinite = 3.0f64.try_into().unwrap(); let mid = lo.midpoint(hi); assert_eq!(mid.get(), 2.0); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.