float16/lib.rs
1//! A crate that provides support for half-precision 16-bit floating point
2//! types.
3//!
4//! This crate provides the [`struct@f16`] type, which is an implementation of
5//! the IEEE 754-2008 standard [`binary16`] a.k.a "half" floating point type.
6//! This 16-bit floating point type is intended for efficient storage where the
7//! full range and precision of a larger floating point value is not required.
8//! This is especially useful for image storage formats.
9//!
10//! This crate also provides a [`struct@bf16`] type, an alternative 16-bit
11//! floating point format. The [`bfloat16`] format is a truncated IEEE 754
12//! standard `binary32` float that preserves the exponent to allow the same
13//! range as [`f32`] but with only 8 bits of precision (instead of 11 bits for
14//! [`struct@f16`]). See the [`struct@bf16`] type for details.
15//!
16//! Because [`struct@f16`] and [`struct@bf16`] are primarily for efficient
17//! storage, floating point operations such as addition, multiplication, etc.
18//! are not always implemented by hardware. When hardware does not support these
19//! operations, this crate emulates them by converting the value to [`f32`]
20//! before performing the operation and then back afterward.
21//!
22//! Note that conversion from [`f32`]/[`f64`] to both [`struct@f16`] and
23//! [`struct@bf16`] are lossy operations, and just as converting a [`f64`] to
24//! [`f32`] is lossy and does not have `Into`/`From` trait implementations, so
25//! too do these smaller types not have those trait implementations either.
26//! Instead, use `from_f32`/`from_f64` functions for the types in this crate.
27//!
28//! The crate supports `#[no_std]` when the `std` cargo feature is not enabled,
29//! so can be used in embedded environments without using the Rust [`std`]
30//! library. The `std` feature enables support for the standard library and is
31//! enabled by default, see the [Cargo Features](#cargo-features) section below.
32//!
33//! # Hardware support
34//!
35//! Hardware support for these conversions and arithmetic will be used
36//! whenever hardware support is available—either through instrinsics or
37//! targeted assembly—although a nightly Rust toolchain may be required for some
38//! hardware. When hardware supports it the functions and traits
39//! [`HalfBitsSliceExt`] and [`HalfFloatSliceExt`] are used it
40//! will also use vectorized SIMD intructions for increased efficiency.
41//!
42//! The following list details hardware support for floating point types in this
43//! crate. When using `std` cargo feature, runtime CPU target detection will be
44//! used. To get the most performance benefits, compile for specific CPU
45//! features which avoids the runtime overhead and works in a
46//! `no_std` environment.
47//!
48//! | Architecture | CPU Target Feature | Notes |
49//! | ------------ | ------------------ | ----- |
50//! | `x86`/`x86_64` | `f16c` | This supports conversion to/from [`struct@f16`] only (including vector SIMD) and does not support any [`struct@bf16`] or arithmetic operations. |
51//! | `aarch64` | `fp16` | This supports all operations on [`struct@f16`] only. |
52//! | `loongarch64` | `lsx` | This supports conversion to/from [`struct@f16`] only (including vector SIMD) and does not support any [`struct@bf16`] or arithmetic operations. |
53//!
54//! # Cargo Features
55//!
56//! To support numerous features, use the [float16-ext] package, which
57//! implements its own `f16` and `bf16` types that support features like
58//! `serde` serializing, zero-copy logic, and more.
59//!
60//! [`std`]: https://doc.rust-lang.org/std/
61//! [`binary16`]: https://en.wikipedia.org/wiki/Half-precision_floating-point_format
62//! [`bfloat16`]: https://en.wikipedia.org/wiki/Bfloat16_floating-point_format
63#![allow(clippy::verbose_bit_mask, clippy::cast_lossless, unexpected_cfgs)]
64#![cfg_attr(not(feature = "std"), no_std)]
65#![doc(html_root_url = "https://docs.rs/float16/0.1.5")]
66#![doc(test(attr(deny(warnings), allow(unused))))]
67// Until updated to use newly stabilized `from_bits`, disable new lint warning about the transmutes
68#![allow(unknown_lints, unnecessary_transmutes)]
69#![warn(unknown_lints)]
70
71mod bfloat;
72mod binary16;
73mod error;
74mod leading_zeros;
75mod slice;
76mod try_from;
77
78pub use bfloat::{bf16, bf16 as Bf16};
79pub use binary16::{f16, f16 as F16};
80pub use error::TryFromFloatError;
81
82#[cfg(not(target_arch = "spirv"))]
83pub use crate::slice::{HalfBitsSliceExt, HalfFloatSliceExt};
84
85// Keep this module private to crate
86mod private {
87 use crate::{bf16, f16};
88
89 pub trait SealedHalf {}
90
91 impl SealedHalf for f16 {
92 }
93 impl SealedHalf for bf16 {
94 }
95}