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`
This commit is contained in:
Matthias Krüger 2025-08-27 11:26:50 +02:00 committed by GitHub
commit c0cd29ed66
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 79 additions and 10 deletions

View File

@ -630,6 +630,13 @@ impl f128 {
/// Converts radians to degrees.
///
/// # Unspecified precision
///
/// The precision of this function is non-deterministic. This means it varies by platform,
/// Rust version, and can even differ within the same execution from one invocation to the next.
///
/// # Examples
///
/// ```
/// #![feature(f128)]
/// # // FIXME(f16_f128): remove when `eqtf2` is available
@ -645,13 +652,22 @@ impl f128 {
#[unstable(feature = "f128", issue = "116909")]
#[must_use = "this returns the result of the operation, without modifying the original"]
pub const fn to_degrees(self) -> Self {
// Use a literal for better precision.
const PIS_IN_180: f128 = 57.2957795130823208767981548141051703324054724665643215491602_f128;
// The division here is correctly rounded with respect to the true value of 180/π.
// Although π is irrational and already rounded, the double rounding happens
// to produce correct result for f128.
const PIS_IN_180: f128 = 180.0 / consts::PI;
self * PIS_IN_180
}
/// Converts degrees to radians.
///
/// # Unspecified precision
///
/// The precision of this function is non-deterministic. This means it varies by platform,
/// Rust version, and can even differ within the same execution from one invocation to the next.
///
/// # Examples
///
/// ```
/// #![feature(f128)]
/// # // FIXME(f16_f128): remove when `eqtf2` is available
@ -668,7 +684,8 @@ impl f128 {
#[unstable(feature = "f128", issue = "116909")]
#[must_use = "this returns the result of the operation, without modifying the original"]
pub const fn to_radians(self) -> f128 {
// Use a literal for better precision.
// Use a literal to avoid double rounding, consts::PI is already rounded,
// and dividing would round again.
const RADS_PER_DEG: f128 =
0.0174532925199432957692369076848861271344287188854172545609719_f128;
self * RADS_PER_DEG

View File

@ -625,6 +625,13 @@ impl f16 {
/// Converts radians to degrees.
///
/// # Unspecified precision
///
/// The precision of this function is non-deterministic. This means it varies by platform,
/// Rust version, and can even differ within the same execution from one invocation to the next.
///
/// # Examples
///
/// ```
/// #![feature(f16)]
/// # // FIXME(f16_f128): extendhfsf2, truncsfhf2, __gnu_h2f_ieee, __gnu_f2h_ieee missing for many platforms
@ -640,13 +647,21 @@ impl f16 {
#[unstable(feature = "f16", issue = "116909")]
#[must_use = "this returns the result of the operation, without modifying the original"]
pub const fn to_degrees(self) -> Self {
// Use a literal for better precision.
// Use a literal to avoid double rounding, consts::PI is already rounded,
// and dividing would round again.
const PIS_IN_180: f16 = 57.2957795130823208767981548141051703_f16;
self * PIS_IN_180
}
/// Converts degrees to radians.
///
/// # Unspecified precision
///
/// The precision of this function is non-deterministic. This means it varies by platform,
/// Rust version, and can even differ within the same execution from one invocation to the next.
///
/// # Examples
///
/// ```
/// #![feature(f16)]
/// # // FIXME(f16_f128): extendhfsf2, truncsfhf2, __gnu_h2f_ieee, __gnu_f2h_ieee missing for many platforms
@ -663,7 +678,8 @@ impl f16 {
#[unstable(feature = "f16", issue = "116909")]
#[must_use = "this returns the result of the operation, without modifying the original"]
pub const fn to_radians(self) -> f16 {
// Use a literal for better precision.
// Use a literal to avoid double rounding, consts::PI is already rounded,
// and dividing would round again.
const RADS_PER_DEG: f16 = 0.017453292519943295769236907684886_f16;
self * RADS_PER_DEG
}

View File

@ -839,6 +839,13 @@ impl f32 {
/// Converts radians to degrees.
///
/// # Unspecified precision
///
/// The precision of this function is non-deterministic. This means it varies by platform,
/// Rust version, and can even differ within the same execution from one invocation to the next.
///
/// # Examples
///
/// ```
/// let angle = std::f32::consts::PI;
///
@ -852,13 +859,21 @@ impl f32 {
#[rustc_const_stable(feature = "const_float_methods", since = "1.85.0")]
#[inline]
pub const fn to_degrees(self) -> f32 {
// Use a constant for better precision.
// Use a literal to avoid double rounding, consts::PI is already rounded,
// and dividing would round again.
const PIS_IN_180: f32 = 57.2957795130823208767981548141051703_f32;
self * PIS_IN_180
}
/// Converts degrees to radians.
///
/// # Unspecified precision
///
/// The precision of this function is non-deterministic. This means it varies by platform,
/// Rust version, and can even differ within the same execution from one invocation to the next.
///
/// # Examples
///
/// ```
/// let angle = 180.0f32;
///
@ -872,6 +887,9 @@ impl f32 {
#[rustc_const_stable(feature = "const_float_methods", since = "1.85.0")]
#[inline]
pub const fn to_radians(self) -> f32 {
// The division here is correctly rounded with respect to the true value of π/180.
// Although π is irrational and already rounded, the double rounding happens
// to produce correct result for f32.
const RADS_PER_DEG: f32 = consts::PI / 180.0;
self * RADS_PER_DEG
}

View File

@ -856,6 +856,13 @@ impl f64 {
/// Converts radians to degrees.
///
/// # Unspecified precision
///
/// The precision of this function is non-deterministic. This means it varies by platform,
/// Rust version, and can even differ within the same execution from one invocation to the next.
///
/// # Examples
///
/// ```
/// let angle = std::f64::consts::PI;
///
@ -869,14 +876,22 @@ impl f64 {
#[rustc_const_stable(feature = "const_float_methods", since = "1.85.0")]
#[inline]
pub const fn to_degrees(self) -> f64 {
// 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.0f64 / consts::PI)
// The division here is correctly rounded with respect to the true value of 180/π.
// Although π is irrational and already rounded, the double rounding happens
// to produce correct result for f64.
const PIS_IN_180: f64 = 180.0 / consts::PI;
self * PIS_IN_180
}
/// Converts degrees to radians.
///
/// # Unspecified precision
///
/// The precision of this function is non-deterministic. This means it varies by platform,
/// Rust version, and can even differ within the same execution from one invocation to the next.
///
/// # Examples
///
/// ```
/// let angle = 180.0_f64;
///
@ -890,6 +905,9 @@ impl f64 {
#[rustc_const_stable(feature = "const_float_methods", since = "1.85.0")]
#[inline]
pub const fn to_radians(self) -> f64 {
// The division here is correctly rounded with respect to the true value of π/180.
// Although π is irrational and already rounded, the double rounding happens
// to produce correct result for f64.
const RADS_PER_DEG: f64 = consts::PI / 180.0;
self * RADS_PER_DEG
}