| 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.