- Pick your favorite math function from the issue tracker.
- Look for the C implementation of the function in the MUSL source code.
- Copy paste the C code into a Rust file in the
src/math
directory and adjustsrc/math/mod.rs
accordingly. Also, uncomment the corresponding trait method insrc/lib.rs
. - Write some simple tests in your module (using
#[test]
) - Run
cargo test
to make sure it works. Full tests are only run when enabling features, see Testing below. - Send us a pull request! Make sure to run
cargo fmt
on your code before sending the PR. Also include "closes #42" in the PR description to close the corresponding issue. - 🎉
Check PR #65 for an example.
-
IMPORTANT The code in this crate will end up being used in the
core
crate so it can not have any external dependencies (other thancore
itself). -
Only use relative imports within the
math
directory / module, e.g.use self::fabs::fabs
oruse super::k_cos
. Absolute imports from core are OK, e.g.use core::u64
. -
To reinterpret a float as an integer use the
to_bits
method. The MUSL code uses theGET_FLOAT_WORD
macro, or a union, to do this operation. -
To reinterpret an integer as a float use the
f32::from_bits
constructor. The MUSL code uses theSET_FLOAT_WORD
macro, or a union, to do this operation. -
You may use other methods from core like
f64::is_nan
, etc. as appropriate. -
If you're implementing one of the private double-underscore functions, take a look at the "source" name in the comment at the top for an idea for alternate naming. For example,
__sin
was renamed tok_sin
after the FreeBSD source code naming. Douse
these private functions inmod.rs
. -
You may encounter weird literals like
0x1p127f
in the MUSL code. These are hexadecimal floating point literals. Rust (the language) doesn't support these kind of literals. This crate provides two macros,hf32!
andhf64!
, which convert string literals to floats at compile time.assert_eq!(hf32!("0x1.ffep+8").to_bits(), 0x43fff000); assert_eq!(hf64!("0x1.ffep+8").to_bits(), 0x407ffe0000000000);
-
Rust code panics on arithmetic overflows when not optimized. You may need to use the
Wrapping
newtype to avoid this problem, or individual methods likewrapping_add
.
Normal tests can be executed with:
cargo test
If you'd like to run tests with randomized inputs that get compared against infinite-precision results, run:
cargo test --features libm-test/test-multiprecision,libm-test/build-musl --release
The multiprecision tests use the rug
crate for bindings to MPFR. MPFR can
be difficult to build on non-Unix systems, refer to gmp_mpfr_sys
for help.
build-musl
does not build with MSVC, Wasm, or Thumb.