11 releases

new 0.1.2 Sep 3, 2024
0.1.1 Aug 18, 2024
0.0.6 Aug 13, 2024

#165 in Math

Download history 352/week @ 2024-08-04 335/week @ 2024-08-11 216/week @ 2024-08-18 5/week @ 2024-08-25 149/week @ 2024-09-01

759 downloads per month

MIT license

42KB
970 lines

metallic

Build status Crates.io Documentation

A fast correctly rounded math library in Rust!

This library is a successor to Metallic, my C library for WebAssembly started in 2017. Its most wanted feature turned out to be math functions I wrote from scratch, so I decided to rewrite them in Rust.

Enable fused multiply-add for best performance!

This crate extensively uses the fused multiply-add instruction if available. Sadly, Rust does not enable it in the default generic target. To achieve best performance, add the following to your .cargo/config.toml either in your project or home directory:

[build]
rustflags = ["-Ctarget-cpu=native"]

Using faster functions from CORE-MATH

I struggle to make some functions faster than CORE-MATH. You can enable the core-math feature in your Cargo.toml:

[dependencies]
metallic = { version = "0.1.2", features = ["core-math"] }

This would replace the following functions with those from core-math:

  • Trigonometric functions for f32
  • f32::powf for correct rounding

Assumptions

C libraries tend to have strict yet obsolete assumptions on math functions. For example, float functions dare not use double instructions for fear that the host does not support them. In this library, I assume all Rust primitive types are IEEE 754 compliant and native to the host. In other words, I assume the following instructions are available to floating-point types:

The assumptions beyond the four basic arithmetic operations creates dependency on the Rust standard library.

Besides, I ignore the floating-point environment, which is not available in Rust. It is also mostly unused in C and C++ because it requires #pragma STDC FENV_ACCESS ON and compiler support. Therefore, the only rounding mode in this library is the default rounding half to even.

Goals

  • The functions should be faithfully rounded (error < 1 ulp).
  • The functions should be about as fast as the system library.
  • Try to make f32 functions faster than the system library.
  • Avoid lookup tables to reduce memory usage, especially on WebAssembly.
    • This goal is not as important as the others. For example, a lookup table for trigonometric functions is required to achieve faithful rounding. See Payne–Hanek reduction for more details.

Non-goals

  • I skip rounding functions such as rint, round, and trunc because

Milestones

  • Real f32/float functions in <math.h>
    • Exponential functions
    • Logarithm with constant base
    • Power and logarithm with arbitrary base
      • Faithful rounding
      • Correct rounding
    • Trigonometric and hyperbolic functions
      • Make trigonometric functions faster than CORE-MATH
    • Miscellaneous elementary functions
    • Non-elementary functions (optional)
  • Complex f32/float functions in <complex.h>
  • Real f64/double functions in <math.h>
  • Complex f64/double functions in <complex.h>

Dependencies

~120–690KB
~12K SLoC