diff --git a/src/libcore/num/f32.rs b/src/libcore/num/f32.rs index b439f5577cbea..bf362928f61c3 100644 --- a/src/libcore/num/f32.rs +++ b/src/libcore/num/f32.rs @@ -259,7 +259,11 @@ impl Float for f32 { #[inline] fn sqrt(self) -> f32 { - unsafe { intrinsics::sqrtf32(self) } + if self < 0.0 { + NAN + } else { + unsafe { intrinsics::sqrtf32(self) } + } } #[inline] diff --git a/src/libcore/num/f64.rs b/src/libcore/num/f64.rs index d980009c0db0d..5ad2e2f9f8b59 100644 --- a/src/libcore/num/f64.rs +++ b/src/libcore/num/f64.rs @@ -266,7 +266,11 @@ impl Float for f64 { #[inline] fn sqrt(self) -> f64 { - unsafe { intrinsics::sqrtf64(self) } + if self < 0.0 { + NAN + } else { + unsafe { intrinsics::sqrtf64(self) } + } } #[inline] @@ -377,4 +381,3 @@ impl Float for f64 { self * (value / 180.0) } } - diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 99d9d1df52220..42ea138acd4dc 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -1501,6 +1501,8 @@ pub trait Float: Signed + Primitive { fn frac_1_sqrt2() -> Self; /// Take the square root of a number. + /// + /// Returns NaN if `self` is not a non-negative number. fn sqrt(self) -> Self; /// Take the reciprocal (inverse) square root of a number, `1/sqrt(x)`. fn rsqrt(self) -> Self; diff --git a/src/libstd/num/f32.rs b/src/libstd/num/f32.rs index b2a9f1b7b20d3..f98e81bb2c878 100644 --- a/src/libstd/num/f32.rs +++ b/src/libstd/num/f32.rs @@ -787,4 +787,15 @@ mod tests { assert_eq!(NEG_INFINITY.integer_decode(), (8388608u64, 105i16, -1i8)); assert_eq!(NAN.integer_decode(), (12582912u64, 105i16, 1i8)); } + + #[test] + fn test_sqrt_domain() { + assert!(NAN.sqrt().is_nan()); + assert!(NEG_INFINITY.sqrt().is_nan()); + assert!((-1.0f32).sqrt().is_nan()); + assert_eq!((-0.0f32).sqrt(), -0.0); + assert_eq!(0.0f32.sqrt(), 0.0); + assert_eq!(1.0f32.sqrt(), 1.0); + assert_eq!(INFINITY.sqrt(), INFINITY); + } } diff --git a/src/libstd/num/f64.rs b/src/libstd/num/f64.rs index 6fe9fcad2aad7..5a5ca65a36de3 100644 --- a/src/libstd/num/f64.rs +++ b/src/libstd/num/f64.rs @@ -789,4 +789,15 @@ mod tests { assert_eq!(NEG_INFINITY.integer_decode(), (4503599627370496, 972, -1)); assert_eq!(NAN.integer_decode(), (6755399441055744u64, 972i16, 1i8)); } + + #[test] + fn test_sqrt_domain() { + assert!(NAN.sqrt().is_nan()); + assert!(NEG_INFINITY.sqrt().is_nan()); + assert!((-1.0f64).sqrt().is_nan()); + assert_eq!((-0.0f64).sqrt(), -0.0); + assert_eq!(0.0f64.sqrt(), 0.0); + assert_eq!(1.0f64.sqrt(), 1.0); + assert_eq!(INFINITY.sqrt(), INFINITY); + } }