From 2d11f0430a99e77ff04c81bd53e4a25058c1e8a7 Mon Sep 17 00:00:00 2001 From: varkor Date: Wed, 28 Feb 2018 22:57:05 +0000 Subject: [PATCH] Fix an accuracy regression in f32::to_degrees #47919 regressed some test cases for `f32::to_degrees`, while improving others. This change satisfies all previous test cases and should be more accurate than both previous implementations. The `f32` to `f64` cast is lossless, `f64::to_degrees` should provide more accuracy than a native `f32::to_degrees`, and conversion back to `f32` will be as accurate a conversion as possible. It can be hard to reason about floating-point accuracy, but given that this passes all the tests, I feel confident it's an improvement. --- src/libcore/num/f32.rs | 4 +--- src/libstd/f32.rs | 4 ++++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/libcore/num/f32.rs b/src/libcore/num/f32.rs index 3586fa5442fb4..38517c5f9c660 100644 --- a/src/libcore/num/f32.rs +++ b/src/libcore/num/f32.rs @@ -239,9 +239,7 @@ impl Float for f32 { /// Converts to degrees, assuming the number is in radians. #[inline] fn to_degrees(self) -> f32 { - // Use a constant for better precision. - const PIS_IN_180: f32 = 57.2957795130823208767981548141051703_f32; - self * PIS_IN_180 + (self as f64).to_degrees() as f32 } /// Converts to radians, assuming the number is in degrees. diff --git a/src/libstd/f32.rs b/src/libstd/f32.rs index a760922115aef..be47604ee7180 100644 --- a/src/libstd/f32.rs +++ b/src/libstd/f32.rs @@ -1532,6 +1532,10 @@ mod tests { assert_eq!(inf.to_degrees(), inf); assert_eq!(neg_inf.to_degrees(), neg_inf); assert_eq!(1_f32.to_degrees(), 57.2957795130823208767981548141051703); + assert_eq!(f32::consts::FRAC_PI_6.to_degrees(), 30.0f32); + assert_eq!(f32::consts::FRAC_PI_3.to_degrees(), 60.0f32); + assert_eq!(30.0f32.to_degrees().to_radians(), 30.0f32); + assert_eq!(30.0f32.to_radians().to_degrees(), 30.0f32); } #[test]