Crates.io | fracints |
lib.rs | fracints |
version | 0.1.0 |
created_at | 2025-05-20 23:03:30.485623+00 |
updated_at | 2025-05-20 23:03:30.485623+00 |
description | Special case fractional-only fixed point numbers |
homepage | |
repository | https://github.com/AaronKutch/fracints |
max_upload_size | |
id | 1682678 |
size | 26,132 |
This crate provides a special case of fixed point numbers in the form of all fractional bits. The fiN
signed types (where the N
is the number of bits) represent values in the range [-1.0, 1.0), and for the fuN
unsigned types [0, 1.0). In calculations, they are treated as if they were integers of the same size but had / 2^N
attached to them.
fiN
) and the 0 to 1 range of real numbers (in the case of fuN
). The size of an ULP of each type is approximately:
fi8
=> 7.81e-3fu8
=> 3.91e-3fi16
=> 3.0517e-5fu16
=> 1.5259e-5fi32
=> 4.6566e-10fu32
=> 2.3283e-10fi64
=> 1.0842e-19fu64
=> 5.4210e-20fi128
=> 5.8775e-39fu128
=> 2.9387e-39fiN::MIN
. However, this crate has special handling for preventing fiN::MIN from being produced, see the section in the docs on preventing overflow.fiN::MIN
)f32
or f64
trigonometry, and generate as little error as is possible (they are <= 0.5 ULP of the true value). This means that one can use perfect trigonometry on a device lacking an fpu.wrapping_X
, overflowing_X
, checked_X
, saturating_X
and others relate to each other), except that the bounds may be NEG_ONE
and ONE
instead of MIN
and MAX
, see the individual function docs for details.fiN::MIN
can be used since it is suggested to avoid it in normal calculations.fi32
is used and 1 ULP is defined as a micrometer, it gives ~4 kilometers of room. If fi64
is used at the nanometer scale, then it gives ~18 million kilometers. If fi128
is used at the 1e-15 meter scale, then it gives ~36 million light years.fiN::ONE
constant uses the true numeric 1 minus 1 ULP. Negative numeric 1 (fiN::MIN
) can be represented exactly by fiN, but as noted elsewhere it leads to all kinds of issues unless carefully handled. I believe that the disadvantage is worth it because of the special cases it avoids (such as no multiplication overflow besides a corner case) and greater idealness it enables.Initial development of all the basics is complete, but I did not get around to implementing unsigned fracints and trigonometry. There are a bunch of TODOs where I know I could improve performance of serialization and some existing algorithms. Any issues or PRs are welcome if someone finds this useful.