Skip to content

Commit 41f2994

Browse files
bors[bot]cuviper
andcommitted
60: Add a special case for sqrt of real numbers r=cuviper a=cuviper Fixes rust-num#59. Co-authored-by: Josh Stone <cuviper@gmail.com>
2 parents f589730 + 980c6bc commit 41f2994

1 file changed

Lines changed: 29 additions & 4 deletions

File tree

src/lib.rs

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -220,10 +220,23 @@ impl<T: Clone + Float> Complex<T> {
220220
/// The branch satisfies `-π/2 ≤ arg(sqrt(z)) ≤ π/2`.
221221
#[inline]
222222
pub fn sqrt(&self) -> Self {
223-
// formula: sqrt(r e^(it)) = sqrt(r) e^(it/2)
224-
let two = T::one() + T::one();
225-
let (r, theta) = self.to_polar();
226-
Self::from_polar(&(r.sqrt()), &(theta / two))
223+
if self.im.is_zero() {
224+
if self.re.is_sign_positive() {
225+
// simple positive real √r, and copy `im` for its sign
226+
Self::new(self.re.sqrt(), self.im)
227+
} else if self.im.is_sign_positive() {
228+
// √(r e^(iπ)) = √r e^(iπ/2) = i√r
229+
Self::new(T::zero(), self.re.abs().sqrt())
230+
} else {
231+
// √(r e^(-iπ)) = √r e^(-iπ/2) = -i√r
232+
Self::new(T::zero(), -self.re.abs().sqrt())
233+
}
234+
} else {
235+
// formula: sqrt(r e^(it)) = sqrt(r) e^(it/2)
236+
let two = T::one() + T::one();
237+
let (r, theta) = self.to_polar();
238+
Self::from_polar(&(r.sqrt()), &(theta / two))
239+
}
227240
}
228241

229242
/// Raises `self` to a floating point power.
@@ -1690,6 +1703,18 @@ mod test {
16901703
}
16911704
}
16921705

1706+
#[test]
1707+
fn test_sqrt_real() {
1708+
for n in (0..100).map(f64::from) {
1709+
// √(n² + 0i) = n + 0i
1710+
assert_eq!(Complex64::new(n * n, 0.0).sqrt(), Complex64::new(n, 0.0));
1711+
// √(-n² + 0i) = 0 + ni
1712+
assert_eq!(Complex64::new(-n * n, 0.0).sqrt(), Complex64::new(0.0, n));
1713+
// √(-n² - 0i) = 0 - ni
1714+
assert_eq!(Complex64::new(-n * n, -0.0).sqrt(), Complex64::new(0.0, -n));
1715+
}
1716+
}
1717+
16931718
#[test]
16941719
fn test_sin() {
16951720
assert!(close(_0_0i.sin(), _0_0i));

0 commit comments

Comments
 (0)