You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
96 lines
3.3 KiB
96 lines
3.3 KiB
4 months ago
|
# 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][src].
|
||
|
- Copy paste the C code into a Rust file in the `src/math` directory and adjust
|
||
|
`src/math/mod.rs` accordingly. Also, uncomment the corresponding trait method
|
||
|
in `src/lib.rs`.
|
||
|
- Write some simple tests in your module (using `#[test]`)
|
||
|
- Run `cargo test` to make sure it works
|
||
|
- Run `cargo test --features musl-reference-tests` to compare your
|
||
|
implementation against musl's
|
||
|
- 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.
|
||
|
- :tada:
|
||
|
|
||
|
[issue tracker]: https://github.com/rust-lang/libm/issues
|
||
|
[src]: https://git.musl-libc.org/cgit/musl/tree/src/math
|
||
|
[`src/math/truncf.rs`]: https://github.com/rust-lang/libm/blob/master/src/math/truncf.rs
|
||
|
|
||
|
Check [PR #65] for an example.
|
||
|
|
||
|
[PR #65]: https://github.com/rust-lang/libm/pull/65
|
||
|
|
||
|
## Tips and tricks
|
||
|
|
||
|
- *IMPORTANT* The code in this crate will end up being used in the `core` crate so it can **not**
|
||
|
have any external dependencies (other than `core` itself).
|
||
|
|
||
|
- Only use relative imports within the `math` directory / module, e.g. `use self::fabs::fabs` or
|
||
|
`use 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 the
|
||
|
`GET_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 the
|
||
|
`SET_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 to `k_sin` after the FreeBSD source code naming. Do `use` these private functions in
|
||
|
`mod.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. The best way I have
|
||
|
found to deal with these literals is to turn them into their integer representation using the
|
||
|
[`hexf!`] macro and then turn them back into floats. See below:
|
||
|
|
||
|
[`hexf!`]: https://crates.io/crates/hexf
|
||
|
|
||
|
``` rust
|
||
|
// 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());
|
||
|
}
|
||
|
```
|
||
|
|
||
|
``` console
|
||
|
$ # Step 2: run the program
|
||
|
$ cargo run
|
||
|
0x7f000000
|
||
|
```
|
||
|
|
||
|
``` rust
|
||
|
// 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 [`Wrapping`]
|
||
|
newtype to avoid this problem.
|
||
|
|
||
|
[`Wrapping`]: https://doc.rust-lang.org/std/num/struct.Wrapping.html
|
||
|
|
||
|
## Testing
|
||
|
|
||
|
Normal tests can be executed with:
|
||
|
|
||
|
```
|
||
|
cargo test
|
||
|
```
|
||
|
|
||
|
If you'd like to run tests with randomized inputs that get compared against musl
|
||
|
itself, you'll need to be on a Linux system and then you can execute:
|
||
|
|
||
|
```
|
||
|
cargo test --features musl-reference-tests
|
||
|
```
|
||
|
|
||
|
Note that you may need to pass `--release` to Cargo if there are errors related
|
||
|
to integer overflow.
|