|
| 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 `src/math/mod.rs` |
| 6 | + accordingly. Also, uncomment the corresponding trait method in `src/lib.rs`. |
| 7 | +- Run `cargo watch check` and fix the compiler errors. |
| 8 | +- Tweak the bottom of `test-generator/src/main.rs` to add your function to the test suite. |
| 9 | +- If you can, run the full test suite locally (see the [testing](#testing) section below). If you |
| 10 | + can't, no problem! Your PR will be fully tested automatically. Though you may still want to add |
| 11 | + and run some unit tests. See the bottom of [`src/math/truncf.rs`] for an example of such tests; |
| 12 | + you can run unit tests with the `cargo test --lib` command. |
| 13 | +- Send us a pull request! |
| 14 | +- :tada: |
| 15 | + |
| 16 | +[issue tracker]: https://github.com/japaric/libm/issues |
| 17 | +[src]: https://git.musl-libc.org/cgit/musl/tree/src/math |
| 18 | +[`src/math/truncf.rs`]: https://github.com/japaric/libm/blob/master/src/math/truncf.rs |
| 19 | + |
| 20 | +Check [PR #65] for an example. |
| 21 | + |
| 22 | +[PR #65]: https://github.com/japaric/libm/pull/65 |
| 23 | + |
| 24 | +## Tips and tricks |
| 25 | + |
| 26 | +- *IMPORTANT* The code in this crate will end up being used in the `core` crate so it can **not** |
| 27 | + have any external dependencies (other than `core` itself). |
| 28 | + |
| 29 | +- Only use relative imports within the `math` directory / module, e.g. `use self::fabs::fabs` or |
| 30 | +`use super::isnanf`. Absolute imports from core are OK, e.g. `use core::u64`. |
| 31 | + |
| 32 | +- To reinterpret a float as an integer use the `to_bits` method. The MUSL code uses the |
| 33 | + `GET_FLOAT_WORD` macro, or a union, to do this operation. |
| 34 | + |
| 35 | +- To reinterpret an integer as a float use the `f32::from_bits` constructor. The MUSL code uses the |
| 36 | + `SET_FLOAT_WORD` macro, or a union, to do this operation. |
| 37 | + |
| 38 | +- You may encounter weird literals like `0x1p127f` in the MUSL code. These are hexadecimal floating |
| 39 | + point literals. Rust (the language) doesn't support these kind of literals. The best way I have |
| 40 | + found to deal with these literals is to turn them into their integer representation using the |
| 41 | + [`hexf!`] macro and then turn them back into floats. See below: |
| 42 | + |
| 43 | +[`hexf!`]: https://crates.io/crates/hexf |
| 44 | + |
| 45 | +``` rust |
| 46 | +// Step 1: write a program to convert the float into its integer representation |
| 47 | +#[macro_use] |
| 48 | +extern crate hexf; |
| 49 | + |
| 50 | +fn main() { |
| 51 | + println!("{:#x}", hexf32!("0x1.0p127").to_bits()); |
| 52 | +} |
| 53 | +``` |
| 54 | + |
| 55 | +``` console |
| 56 | +$ # Step 2: run the program |
| 57 | +$ cargo run |
| 58 | +0x7f000000 |
| 59 | +``` |
| 60 | + |
| 61 | +``` rust |
| 62 | +// Step 3: copy paste the output into libm |
| 63 | +let x1p127 = f32::from_bits(0x7f000000); // 0x1p127f === 2 ^ 12 |
| 64 | +``` |
| 65 | + |
| 66 | +- Rust code panics on arithmetic overflows when not optimized. You may need to use the [`Wrapping`] |
| 67 | + newtype to avoid this problem. |
| 68 | + |
| 69 | +[`Wrapping`]: https://doc.rust-lang.org/std/num/struct.Wrapping.html |
| 70 | + |
| 71 | +## Testing |
| 72 | + |
| 73 | +The test suite of this crate can only be run on x86_64 Linux systems using the following commands: |
| 74 | + |
| 75 | +``` console |
| 76 | +$ # The test suite depends on the `cross` tool so install it if you don't have it |
| 77 | +$ cargo install cross |
| 78 | + |
| 79 | +$ # and the `cross` tool requires docker to be running |
| 80 | +$ systemctl start docker |
| 81 | + |
| 82 | +$ # execute the test suite for the x86_64 target |
| 83 | +$ TARGET=x86_64-unknown-linux-gnu bash ci/script.sh |
| 84 | + |
| 85 | +$ # execute the test suite for the ARMv7 target |
| 86 | +$ TARGET=armv7-unknown-linux-gnueabihf bash ci/script.sh |
| 87 | +``` |
0 commit comments