Skip to content

Commit c0cd29e

Browse files
authored
Rollup merge of #145625 - karolzwolak:f16-use-expr-instead-literal, r=beetrees,tgross35
improve float to_degrees/to_radians rounding comments and impl This PR makes `to_degrees()` and `to_radians()` float functions more consistent between each other and improves comments around their precision and rounding. * revise comments explaining why we are using literal or expression * add unspecified precision comments as we don't guarantee precision * use expression in `f128::to_degrees()` * make `f64::to_degrees()` impl consistent with other functions r? `@tgross35`
2 parents f2eb47a + 698db13 commit c0cd29e

File tree

4 files changed

+79
-10
lines changed

4 files changed

+79
-10
lines changed

library/core/src/num/f128.rs

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -630,6 +630,13 @@ impl f128 {
630630

631631
/// Converts radians to degrees.
632632
///
633+
/// # Unspecified precision
634+
///
635+
/// The precision of this function is non-deterministic. This means it varies by platform,
636+
/// Rust version, and can even differ within the same execution from one invocation to the next.
637+
///
638+
/// # Examples
639+
///
633640
/// ```
634641
/// #![feature(f128)]
635642
/// # // FIXME(f16_f128): remove when `eqtf2` is available
@@ -645,13 +652,22 @@ impl f128 {
645652
#[unstable(feature = "f128", issue = "116909")]
646653
#[must_use = "this returns the result of the operation, without modifying the original"]
647654
pub const fn to_degrees(self) -> Self {
648-
// Use a literal for better precision.
649-
const PIS_IN_180: f128 = 57.2957795130823208767981548141051703324054724665643215491602_f128;
655+
// The division here is correctly rounded with respect to the true value of 180/π.
656+
// Although π is irrational and already rounded, the double rounding happens
657+
// to produce correct result for f128.
658+
const PIS_IN_180: f128 = 180.0 / consts::PI;
650659
self * PIS_IN_180
651660
}
652661

653662
/// Converts degrees to radians.
654663
///
664+
/// # Unspecified precision
665+
///
666+
/// The precision of this function is non-deterministic. This means it varies by platform,
667+
/// Rust version, and can even differ within the same execution from one invocation to the next.
668+
///
669+
/// # Examples
670+
///
655671
/// ```
656672
/// #![feature(f128)]
657673
/// # // FIXME(f16_f128): remove when `eqtf2` is available
@@ -668,7 +684,8 @@ impl f128 {
668684
#[unstable(feature = "f128", issue = "116909")]
669685
#[must_use = "this returns the result of the operation, without modifying the original"]
670686
pub const fn to_radians(self) -> f128 {
671-
// Use a literal for better precision.
687+
// Use a literal to avoid double rounding, consts::PI is already rounded,
688+
// and dividing would round again.
672689
const RADS_PER_DEG: f128 =
673690
0.0174532925199432957692369076848861271344287188854172545609719_f128;
674691
self * RADS_PER_DEG

library/core/src/num/f16.rs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -625,6 +625,13 @@ impl f16 {
625625

626626
/// Converts radians to degrees.
627627
///
628+
/// # Unspecified precision
629+
///
630+
/// The precision of this function is non-deterministic. This means it varies by platform,
631+
/// Rust version, and can even differ within the same execution from one invocation to the next.
632+
///
633+
/// # Examples
634+
///
628635
/// ```
629636
/// #![feature(f16)]
630637
/// # // FIXME(f16_f128): extendhfsf2, truncsfhf2, __gnu_h2f_ieee, __gnu_f2h_ieee missing for many platforms
@@ -640,13 +647,21 @@ impl f16 {
640647
#[unstable(feature = "f16", issue = "116909")]
641648
#[must_use = "this returns the result of the operation, without modifying the original"]
642649
pub const fn to_degrees(self) -> Self {
643-
// Use a literal for better precision.
650+
// Use a literal to avoid double rounding, consts::PI is already rounded,
651+
// and dividing would round again.
644652
const PIS_IN_180: f16 = 57.2957795130823208767981548141051703_f16;
645653
self * PIS_IN_180
646654
}
647655

648656
/// Converts degrees to radians.
649657
///
658+
/// # Unspecified precision
659+
///
660+
/// The precision of this function is non-deterministic. This means it varies by platform,
661+
/// Rust version, and can even differ within the same execution from one invocation to the next.
662+
///
663+
/// # Examples
664+
///
650665
/// ```
651666
/// #![feature(f16)]
652667
/// # // FIXME(f16_f128): extendhfsf2, truncsfhf2, __gnu_h2f_ieee, __gnu_f2h_ieee missing for many platforms
@@ -663,7 +678,8 @@ impl f16 {
663678
#[unstable(feature = "f16", issue = "116909")]
664679
#[must_use = "this returns the result of the operation, without modifying the original"]
665680
pub const fn to_radians(self) -> f16 {
666-
// Use a literal for better precision.
681+
// Use a literal to avoid double rounding, consts::PI is already rounded,
682+
// and dividing would round again.
667683
const RADS_PER_DEG: f16 = 0.017453292519943295769236907684886_f16;
668684
self * RADS_PER_DEG
669685
}

library/core/src/num/f32.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -839,6 +839,13 @@ impl f32 {
839839

840840
/// Converts radians to degrees.
841841
///
842+
/// # Unspecified precision
843+
///
844+
/// The precision of this function is non-deterministic. This means it varies by platform,
845+
/// Rust version, and can even differ within the same execution from one invocation to the next.
846+
///
847+
/// # Examples
848+
///
842849
/// ```
843850
/// let angle = std::f32::consts::PI;
844851
///
@@ -852,13 +859,21 @@ impl f32 {
852859
#[rustc_const_stable(feature = "const_float_methods", since = "1.85.0")]
853860
#[inline]
854861
pub const fn to_degrees(self) -> f32 {
855-
// Use a constant for better precision.
862+
// Use a literal to avoid double rounding, consts::PI is already rounded,
863+
// and dividing would round again.
856864
const PIS_IN_180: f32 = 57.2957795130823208767981548141051703_f32;
857865
self * PIS_IN_180
858866
}
859867

860868
/// Converts degrees to radians.
861869
///
870+
/// # Unspecified precision
871+
///
872+
/// The precision of this function is non-deterministic. This means it varies by platform,
873+
/// Rust version, and can even differ within the same execution from one invocation to the next.
874+
///
875+
/// # Examples
876+
///
862877
/// ```
863878
/// let angle = 180.0f32;
864879
///
@@ -872,6 +887,9 @@ impl f32 {
872887
#[rustc_const_stable(feature = "const_float_methods", since = "1.85.0")]
873888
#[inline]
874889
pub const fn to_radians(self) -> f32 {
890+
// The division here is correctly rounded with respect to the true value of π/180.
891+
// Although π is irrational and already rounded, the double rounding happens
892+
// to produce correct result for f32.
875893
const RADS_PER_DEG: f32 = consts::PI / 180.0;
876894
self * RADS_PER_DEG
877895
}

library/core/src/num/f64.rs

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -856,6 +856,13 @@ impl f64 {
856856

857857
/// Converts radians to degrees.
858858
///
859+
/// # Unspecified precision
860+
///
861+
/// The precision of this function is non-deterministic. This means it varies by platform,
862+
/// Rust version, and can even differ within the same execution from one invocation to the next.
863+
///
864+
/// # Examples
865+
///
859866
/// ```
860867
/// let angle = std::f64::consts::PI;
861868
///
@@ -869,14 +876,22 @@ impl f64 {
869876
#[rustc_const_stable(feature = "const_float_methods", since = "1.85.0")]
870877
#[inline]
871878
pub const fn to_degrees(self) -> f64 {
872-
// The division here is correctly rounded with respect to the true
873-
// value of 180/π. (This differs from f32, where a constant must be
874-
// used to ensure a correctly rounded result.)
875-
self * (180.0f64 / consts::PI)
879+
// The division here is correctly rounded with respect to the true value of 180/π.
880+
// Although π is irrational and already rounded, the double rounding happens
881+
// to produce correct result for f64.
882+
const PIS_IN_180: f64 = 180.0 / consts::PI;
883+
self * PIS_IN_180
876884
}
877885

878886
/// Converts degrees to radians.
879887
///
888+
/// # Unspecified precision
889+
///
890+
/// The precision of this function is non-deterministic. This means it varies by platform,
891+
/// Rust version, and can even differ within the same execution from one invocation to the next.
892+
///
893+
/// # Examples
894+
///
880895
/// ```
881896
/// let angle = 180.0_f64;
882897
///
@@ -890,6 +905,9 @@ impl f64 {
890905
#[rustc_const_stable(feature = "const_float_methods", since = "1.85.0")]
891906
#[inline]
892907
pub const fn to_radians(self) -> f64 {
908+
// The division here is correctly rounded with respect to the true value of π/180.
909+
// Although π is irrational and already rounded, the double rounding happens
910+
// to produce correct result for f64.
893911
const RADS_PER_DEG: f64 = consts::PI / 180.0;
894912
self * RADS_PER_DEG
895913
}

0 commit comments

Comments
 (0)