#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] pubfn sqrt(x: f64) -> f64 { // On wasm32 we know that LLVM's intrinsic will compile to an optimized // `f64.sqrt` native instruction, so we can leverage this for both code size // and speed.
llvm_intrinsically_optimized! { #[cfg(target_arch = "wasm32")] { returnif x < 0.0 {
f64::NAN
} else { unsafe { ::core::intrinsics::sqrtf64(x) }
}
}
} #[cfg(target_feature = "sse2")]
{ // Note: This path is unlikely since LLVM will usually have already // optimized sqrt calls into hardware instructions if sse2 is available, // but if someone does end up here they'll apprected the speed increase. #[cfg(target_arch = "x86")] use core::arch::x86::*; #[cfg(target_arch = "x86_64")] use core::arch::x86_64::*; unsafe { let m = _mm_set_sd(x); let m_sqrt = _mm_sqrt_pd(m);
_mm_cvtsd_f64(m_sqrt)
}
} #[cfg(not(target_feature = "sse2"))]
{ use core::num::Wrapping;
ix0 = (x.to_bits() >> 32) as i32;
ix1 = Wrapping(x.to_bits() as u32);
/* take care of Inf and NaN */ if (ix0 & 0x7ff00000) == 0x7ff00000 { return x * x + x; /* sqrt(NaN)=NaN, sqrt(+inf)=+inf, sqrt(-inf)=sNaN */
} /* take care of zero */ if ix0 <= 0 { if ((ix0 & !(sign.0as i32)) | ix1.0as i32) == 0 { return x; /* sqrt(+-0) = +-0 */
} if ix0 < 0 { return (x - x) / (x - x); /* sqrt(-ve) = sNaN */
}
} /* normalize x */
m = ix0 >> 20; if m == 0 { /* subnormal x */ while ix0 == 0 {
m -= 21;
ix0 |= (ix1 >> 11).0as i32;
ix1 <<= 21;
}
i = 0; while (ix0 & 0x00100000) == 0 {
i += 1;
ix0 <<= 1;
}
m -= i - 1;
ix0 |= (ix1 >> (32 - i) as usize).0as i32;
ix1 = ix1 << i as usize;
}
m -= 1023; /* unbias exponent */
ix0 = (ix0 & 0x000fffff) | 0x00100000; if (m & 1) == 1 { /* odd m, double x to make it even */
ix0 += ix0 + ((ix1 & sign) >> 31).0as i32;
ix1 += ix1;
}
m >>= 1; /* m = [m/2] */
/* generate sqrt(x) bit by bit */
ix0 += ix0 + ((ix1 & sign) >> 31).0as i32;
ix1 += ix1;
q = 0; /* [q,q1] = sqrt(x) */
q1 = Wrapping(0);
s0 = 0;
s1 = Wrapping(0);
r = Wrapping(0x00200000); /* r = moving bit from right to left */
while r != Wrapping(0) {
t = s0 + r.0as i32; if t <= ix0 {
s0 = t + r.0as i32;
ix0 -= t;
q += r.0as i32;
}
ix0 += ix0 + ((ix1 & sign) >> 31).0as i32;
ix1 += ix1;
r >>= 1;
}
r = sign; while r != Wrapping(0) {
t1 = s1 + r;
t = s0; if t < ix0 || (t == ix0 && t1 <= ix1) {
s1 = t1 + r; if (t1 & sign) == sign && (s1 & sign) == Wrapping(0) {
s0 += 1;
}
ix0 -= t; if ix1 < t1 {
ix0 -= 1;
}
ix1 -= t1;
q1 += r;
}
ix0 += ix0 + ((ix1 & sign) >> 31).0as i32;
ix1 += ix1;
r >>= 1;
}
/* use floating add to find out rounding direction */ if (ix0 as u32 | ix1.0) != 0 {
z = 1.0 - TINY; /* raise inexact flag */ if z >= 1.0 {
z = 1.0 + TINY; if q1.0 == 0xffffffff {
q1 = Wrapping(0);
q += 1;
} elseif z > 1.0 { if q1.0 == 0xfffffffe {
q += 1;
}
q1 += Wrapping(2);
} else {
q1 += q1 & Wrapping(1);
}
}
}
ix0 = (q >> 1) + 0x3fe00000;
ix1 = q1 >> 1; if (q & 1) == 1 {
ix1 |= sign;
}
ix0 += m << 20;
f64::from_bits((ix0 as u64) << 32 | ix1.0as u64)
}
}
#[cfg(test)] mod tests { usesuper::*; use core::f64::*;
/// The spec: https://en.cppreference.com/w/cpp/numeric/math/sqrt #[test] fn spec_tests() { // Not Asserted: FE_INVALID exception is raised if argument is negative.
assert!(sqrt(-1.0).is_nan());
assert!(sqrt(NAN).is_nan()); for f in [0.0, -0.0, INFINITY].iter().copied() {
assert_eq!(sqrt(f), f);
}
}
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.13 Sekunden
(vorverarbeitet am 2026-06-18)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.