Merge #61
61: Use constant for 180/π in f32::to_degrees r=cuviper a=vks
The current `f32::to_degrees` implementation uses a division to
calculate 180/π, which causes a loss of precision. Using a constant is
still not perfect (implementing a maximally-precise algorithm would come
with a high performance cost), but improves precision with a minimal
change.
This is a backport from [`std`].
[`std`]: e34c31bf02
Co-authored-by: Vinzent Steinberg <vinzent.steinberg@gmail.com>
Co-authored-by: Josh Stone <cuviper@gmail.com>
This commit is contained in:
commit
dd67e9d2e1
17
src/float.rs
17
src/float.rs
|
@ -771,7 +771,9 @@ impl FloatCore for f32 {
|
|||
#[inline]
|
||||
#[cfg(not(feature = "std"))]
|
||||
fn to_degrees(self) -> Self {
|
||||
self * (180.0 / f32::consts::PI)
|
||||
// Use a constant for better precision.
|
||||
const PIS_IN_180: f32 = 57.2957795130823208767981548141051703_f32;
|
||||
self * PIS_IN_180
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -841,6 +843,9 @@ impl FloatCore for f64 {
|
|||
#[inline]
|
||||
#[cfg(not(feature = "std"))]
|
||||
fn to_degrees(self) -> Self {
|
||||
// The division here is correctly rounded with respect to the true
|
||||
// value of 180/π. (This differs from f32, where a constant must be
|
||||
// used to ensure a correctly rounded result.)
|
||||
self * (180.0 / f64::consts::PI)
|
||||
}
|
||||
|
||||
|
@ -2008,4 +2013,14 @@ mod tests {
|
|||
assert!((Float::to_radians(deg) - rad).abs() < 1e-5);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
// This fails with the forwarded `std` implementation in Rust 1.8.
|
||||
// To avoid the failure, the test is limited to `no_std` builds.
|
||||
#[cfg(not(feature = "std"))]
|
||||
fn to_degrees_rounding() {
|
||||
use float::FloatCore;
|
||||
|
||||
assert_eq!(FloatCore::to_degrees(1_f32), 57.2957795130823208767981548141051703);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue