Skip to content

Commit 93c4cee

Browse files
committed
Add newlib cbrtf
1 parent ecf6ee7 commit 93c4cee

File tree

1 file changed

+61
-0
lines changed

1 file changed

+61
-0
lines changed

Diff for: src/math/cbrtf.rs

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
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

Comments
 (0)