3.4 KiB
How to contribute
- 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/mathdirectory and adjustsrc/math/mod.rsaccordingly. Also, uncomment the corresponding trait method insrc/lib.rs. - Run
cargo watch checkand fix the compiler errors. - Tweak the bottom of
test-generator/src/main.rsto add your function to the test suite. - If you can, run the full test suite locally (see the testing section below). If you
can't, no problem! Your PR will be fully tested automatically. Though you may still want to add
and run some unit tests. See the bottom of
src/math/truncf.rsfor an example of such tests; you can run unit tests with thecargo test --libcommand. - Send us a pull request! Make sure to run
cargo fmton 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.
Tips and tricks
-
IMPORTANT The code in this crate will end up being used in the
corecrate so it can not have any external dependencies (other thancoreitself). -
Only use relative imports within the
mathdirectory / module, e.g.use self::fabs::fabsoruse super::isnanf. Absolute imports from core are OK, e.g.use core::u64. -
To reinterpret a float as an integer use the
to_bitsmethod. The MUSL code uses theGET_FLOAT_WORDmacro, or a union, to do this operation. -
To reinterpret an integer as a float use the
f32::from_bitsconstructor. The MUSL code uses theSET_FLOAT_WORDmacro, or a union, to do this operation. -
You may encounter weird literals like
0x1p127fin the MUSL code. These are hexadecimal floating point literals. Rust (the language) doesn't support these kind of literals. The best way I have found to deal with these literals is to turn them into their integer representation using thehexf!macro and then turn them back into floats. See below:
// Step 1: write a program to convert the float into its integer representation
#[macro_use]
extern crate hexf;
fn main() {
println!("{:#x}", hexf32!("0x1.0p127").to_bits());
}
$ # Step 2: run the program
$ cargo run
0x7f000000
// Step 3: copy paste the output into libm
let x1p127 = f32::from_bits(0x7f000000); // 0x1p127f === 2 ^ 12
- Rust code panics on arithmetic overflows when not optimized. You may need to use the
Wrappingnewtype to avoid this problem.
Testing
The test suite of this crate can only be run on x86_64 Linux systems using the following commands:
$ # The test suite depends on the `cross` tool so install it if you don't have it
$ cargo install cross
$ # and the `cross` tool requires docker to be running
$ systemctl start docker
$ # execute the test suite for the x86_64 target
$ TARGET=x86_64-unknown-linux-gnu bash ci/script.sh
$ # execute the test suite for the ARMv7 target
$ TARGET=armv7-unknown-linux-gnueabihf bash ci/script.sh