1# How to contribute 2 3- Pick your favorite math function from the [issue tracker]. 4- Look for the C implementation of the function in the [MUSL source code][src]. 5- Copy paste the C code into a Rust file in the `src/math` directory and adjust 6 `src/math/mod.rs` accordingly. Also, uncomment the corresponding trait method 7 in `src/lib.rs`. 8- Write some simple tests in your module (using `#[test]`) 9- Run `cargo test` to make sure it works 10- Run `cargo test --features musl-reference-tests` to compare your 11 implementation against musl's 12- Send us a pull request! Make sure to run `cargo fmt` on your code before 13 sending the PR. Also include "closes #42" in the PR description to close the 14 corresponding issue. 15- :tada: 16 17[issue tracker]: https://github.com/rust-lang/libm/issues 18[src]: https://git.musl-libc.org/cgit/musl/tree/src/math 19[`src/math/truncf.rs`]: https://github.com/rust-lang/libm/blob/master/src/math/truncf.rs 20 21Check [PR #65] for an example. 22 23[PR #65]: https://github.com/rust-lang/libm/pull/65 24 25## Tips and tricks 26 27- *IMPORTANT* The code in this crate will end up being used in the `core` crate so it can **not** 28 have any external dependencies (other than `core` itself). 29 30- Only use relative imports within the `math` directory / module, e.g. `use self::fabs::fabs` or 31`use super::k_cos`. Absolute imports from core are OK, e.g. `use core::u64`. 32 33- To reinterpret a float as an integer use the `to_bits` method. The MUSL code uses the 34 `GET_FLOAT_WORD` macro, or a union, to do this operation. 35 36- To reinterpret an integer as a float use the `f32::from_bits` constructor. The MUSL code uses the 37 `SET_FLOAT_WORD` macro, or a union, to do this operation. 38 39- You may use other methods from core like `f64::is_nan`, etc. as appropriate. 40 41- If you're implementing one of the private double-underscore functions, take a look at the 42 "source" name in the comment at the top for an idea for alternate naming. For example, `__sin` 43 was renamed to `k_sin` after the FreeBSD source code naming. Do `use` these private functions in 44 `mod.rs`. 45 46- You may encounter weird literals like `0x1p127f` in the MUSL code. These are hexadecimal floating 47 point literals. Rust (the language) doesn't support these kind of literals. The best way I have 48 found to deal with these literals is to turn them into their integer representation using the 49 [`hexf!`] macro and then turn them back into floats. See below: 50 51[`hexf!`]: https://crates.io/crates/hexf 52 53``` rust 54// Step 1: write a program to convert the float into its integer representation 55#[macro_use] 56extern crate hexf; 57 58fn main() { 59 println!("{:#x}", hexf32!("0x1.0p127").to_bits()); 60} 61``` 62 63``` console 64$ # Step 2: run the program 65$ cargo run 660x7f000000 67``` 68 69``` rust 70// Step 3: copy paste the output into libm 71let x1p127 = f32::from_bits(0x7f000000); // 0x1p127f === 2 ^ 12 72``` 73 74- Rust code panics on arithmetic overflows when not optimized. You may need to use the [`Wrapping`] 75 newtype to avoid this problem. 76 77[`Wrapping`]: https://doc.rust-lang.org/std/num/struct.Wrapping.html 78 79## Testing 80 81Normal tests can be executed with: 82 83``` 84cargo test 85``` 86 87If you'd like to run tests with randomized inputs that get compared against musl 88itself, you'll need to be on a Linux system and then you can execute: 89 90``` 91cargo test --features musl-reference-tests 92``` 93 94Note that you may need to pass `--release` to Cargo if there are errors related 95to integer overflow. 96