|
| 1 | +/* sf_cbrt.c -- float version of s_cbrt.c. |
| 2 | + * Conversion to float by Ian Lance Taylor, Cygnus Support, [email protected]. |
| 3 | + */ |
| 4 | + |
| 5 | +/* |
| 6 | + * ==================================================== |
| 7 | + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. |
| 8 | + * |
| 9 | + * Developed at SunPro, a Sun Microsystems, Inc. business. |
| 10 | + * Permission to use, copy, modify, and distribute this |
| 11 | + * software is freely granted, provided that this notice |
| 12 | + * is preserved. |
| 13 | + * ==================================================== |
| 14 | + * |
| 15 | + */ |
| 16 | + |
| 17 | +use super::fdlibm::{FLT_UWORD_IS_FINITE, FLT_UWORD_IS_SUBNORMAL, FLT_UWORD_IS_ZERO}; |
| 18 | + |
| 19 | +const B1: u32 = 709_958_130; /* B1 = (84+2/3-0.03306235651)*2**23 */ |
| 20 | +const B2: u32 = 642_849_266; /* B2 = (76+2/3-0.03306235651)*2**23 */ |
| 21 | + |
| 22 | +const C: f32 = 5.428_571_701_0e-01; /* 19/35 = 0x3f0a_f8b0 */ |
| 23 | +const D: f32 = -7.053_061_127_7e-01; /* -864/1225 = 0xbf34_8ef1 */ |
| 24 | +const E: f32 = 1.414_285_659_8e+00; /* 99/70 = 0x3fb5_0750 */ |
| 25 | +const F: f32 = 1.607_142_806_1e+00; /* 45/28 = 0x3fcd_b6db */ |
| 26 | +const G: f32 = 3.571_428_656_6e-01; /* 5/14 = 0x3eb6_db6e */ |
| 27 | + |
| 28 | +/// Cube root (f32) |
| 29 | +/// |
| 30 | +/// Computes the cube root of the argument. |
| 31 | +#[inline] |
| 32 | +#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] |
| 33 | +pub fn cbrtf(x: f32) -> f32 { |
| 34 | + let hx: u32 = x.to_bits() & 0x7fff_ffff; /* |x| */ |
| 35 | + let sign: u32 = x.to_bits() & 0x8000_0000; /* sign = sign(x) */ |
| 36 | + |
| 37 | + if !FLT_UWORD_IS_FINITE(hx) { |
| 38 | + return x + x; /* cbrt(NaN,INF) is itself */ |
| 39 | + } |
| 40 | + if FLT_UWORD_IS_ZERO(hx) { |
| 41 | + return x; /* cbrt(0) is itself */ |
| 42 | + } |
| 43 | + |
| 44 | + let x = f32::from_bits(hx); /* x <- |x| */ |
| 45 | + /* rough cbrt to 5 bits */ |
| 46 | + let mut t: f32 = if FLT_UWORD_IS_SUBNORMAL(hx) { |
| 47 | + /* subnormal number */ |
| 48 | + let high: u32 = (x * f32::from_bits(0x4b80_0000)).to_bits(); /* x * (2 ^ 24)*/ |
| 49 | + f32::from_bits(high / 3 + B2) |
| 50 | + } else { |
| 51 | + f32::from_bits(hx / 3 + B1) |
| 52 | + }; |
| 53 | + |
| 54 | + /* new cbrt to 23 bits */ |
| 55 | + let r: f32 = t * t / x; |
| 56 | + let s: f32 = C + r * t; |
| 57 | + t *= G + F / (s + E + D / s); |
| 58 | + |
| 59 | + /* retore the sign bit */ |
| 60 | + f32::from_bits(t.to_bits() | sign) |
| 61 | +} |
0 commit comments