Skip to content
This repository was archived by the owner on Apr 28, 2025. It is now read-only.

Commit b6f37c6

Browse files
committed
Add frexpf16, frexpf128, ilogbf16, and ilogbf128
1 parent 63b76f0 commit b6f37c6

File tree

13 files changed

+162
-37
lines changed

13 files changed

+162
-37
lines changed

crates/libm-macros/src/shared.rs

+28
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,13 @@ const ALL_OPERATIONS_NESTED: &[(FloatTy, Signature, Option<Signature>, &[&str])]
106106
None,
107107
&["fma"],
108108
),
109+
(
110+
// `(f16) -> i32`
111+
FloatTy::F16,
112+
Signature { args: &[Ty::F16], returns: &[Ty::I32] },
113+
None,
114+
&["ilogbf16"],
115+
),
109116
(
110117
// `(f32) -> i32`
111118
FloatTy::F32,
@@ -120,6 +127,13 @@ const ALL_OPERATIONS_NESTED: &[(FloatTy, Signature, Option<Signature>, &[&str])]
120127
None,
121128
&["ilogb"],
122129
),
130+
(
131+
// `(f128) -> i32`
132+
FloatTy::F128,
133+
Signature { args: &[Ty::F128], returns: &[Ty::I32] },
134+
None,
135+
&["ilogbf128"],
136+
),
123137
(
124138
// `(i32, f32) -> f32`
125139
FloatTy::F32,
@@ -162,6 +176,13 @@ const ALL_OPERATIONS_NESTED: &[(FloatTy, Signature, Option<Signature>, &[&str])]
162176
Some(Signature { args: &[Ty::F64, Ty::MutF64], returns: &[Ty::F64] }),
163177
&["modf"],
164178
),
179+
(
180+
// `(f16, &mut c_int) -> f16` as `(f16) -> (f16, i32)`
181+
FloatTy::F16,
182+
Signature { args: &[Ty::F16], returns: &[Ty::F16, Ty::I32] },
183+
Some(Signature { args: &[Ty::F16, Ty::MutCInt], returns: &[Ty::F16] }),
184+
&["frexpf16"],
185+
),
165186
(
166187
// `(f32, &mut c_int) -> f32` as `(f32) -> (f32, i32)`
167188
FloatTy::F32,
@@ -176,6 +197,13 @@ const ALL_OPERATIONS_NESTED: &[(FloatTy, Signature, Option<Signature>, &[&str])]
176197
Some(Signature { args: &[Ty::F64, Ty::MutCInt], returns: &[Ty::F64] }),
177198
&["frexp", "lgamma_r"],
178199
),
200+
(
201+
// `(f128, &mut c_int) -> f128` as `(f128) -> (f128, i32)`
202+
FloatTy::F128,
203+
Signature { args: &[Ty::F128], returns: &[Ty::F128, Ty::I32] },
204+
Some(Signature { args: &[Ty::F128, Ty::MutCInt], returns: &[Ty::F128] }),
205+
&["frexpf128"],
206+
),
179207
(
180208
// `(f32, f32, &mut c_int) -> f32` as `(f32, f32) -> (f32, i32)`
181209
FloatTy::F32,

crates/libm-test/benches/random.rs

+4
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,10 @@ libm_macros::for_each_function! {
133133
| fminf16
134134
| fmodf128
135135
| fmodf16
136+
| frexpf128
137+
| frexpf16
138+
| ilogbf128
139+
| ilogbf16
136140
| rintf128
137141
| rintf16
138142
| roundf128

crates/libm-test/src/mpfloat.rs

+46-37
Original file line numberDiff line numberDiff line change
@@ -153,8 +153,12 @@ libm_macros::for_each_function! {
153153
fmodf16,
154154
frexp,
155155
frexpf,
156+
frexpf128,
157+
frexpf16,
156158
ilogb,
157159
ilogbf,
160+
ilogbf128,
161+
ilogbf16,
158162
jn,
159163
jnf,
160164
ldexp,
@@ -299,43 +303,6 @@ macro_rules! impl_op_for_ty {
299303
}
300304
}
301305

302-
impl MpOp for crate::op::[<frexp $suffix>]::Routine {
303-
type MpTy = MpFloat;
304-
305-
fn new_mp() -> Self::MpTy {
306-
new_mpfloat::<Self::FTy>()
307-
}
308-
309-
fn run(this: &mut Self::MpTy, input: Self::RustArgs) -> Self::RustRet {
310-
this.assign(input.0);
311-
let exp = this.frexp_mut();
312-
(prep_retval::<Self::FTy>(this, Ordering::Equal), exp)
313-
}
314-
}
315-
316-
impl MpOp for crate::op::[<ilogb $suffix>]::Routine {
317-
type MpTy = MpFloat;
318-
319-
fn new_mp() -> Self::MpTy {
320-
new_mpfloat::<Self::FTy>()
321-
}
322-
323-
fn run(this: &mut Self::MpTy, input: Self::RustArgs) -> Self::RustRet {
324-
this.assign(input.0);
325-
326-
// `get_exp` follows `frexp` for `0.5 <= |m| < 1.0`. Adjust the exponent by
327-
// one to scale the significand to `1.0 <= |m| < 2.0`.
328-
this.get_exp().map(|v| v - 1).unwrap_or_else(|| {
329-
if this.is_infinite() {
330-
i32::MAX
331-
} else {
332-
// Zero or NaN
333-
i32::MIN
334-
}
335-
})
336-
}
337-
}
338-
339306
impl MpOp for crate::op::[<jn $suffix>]::Routine {
340307
type MpTy = MpFloat;
341308

@@ -466,6 +433,48 @@ macro_rules! impl_op_for_ty_all {
466433
prep_retval::<Self::RustRet>(&mut this.0, ord)
467434
}
468435
}
436+
437+
impl MpOp for crate::op::[<frexp $suffix>]::Routine {
438+
type MpTy = MpFloat;
439+
440+
fn new_mp() -> Self::MpTy {
441+
new_mpfloat::<Self::FTy>()
442+
}
443+
444+
fn run(this: &mut Self::MpTy, input: Self::RustArgs) -> Self::RustRet {
445+
// Implementation taken from `rug::Float::to_f32_exp`.
446+
this.assign(input.0);
447+
let exp = this.get_exp().unwrap_or(0);
448+
if exp != 0 {
449+
*this >>= exp;
450+
}
451+
452+
(prep_retval::<Self::FTy>(this, Ordering::Equal), exp)
453+
}
454+
}
455+
456+
impl MpOp for crate::op::[<ilogb $suffix>]::Routine {
457+
type MpTy = MpFloat;
458+
459+
fn new_mp() -> Self::MpTy {
460+
new_mpfloat::<Self::FTy>()
461+
}
462+
463+
fn run(this: &mut Self::MpTy, input: Self::RustArgs) -> Self::RustRet {
464+
this.assign(input.0);
465+
466+
// `get_exp` follows `frexp` for `0.5 <= |m| < 1.0`. Adjust the exponent by
467+
// one to scale the significand to `1.0 <= |m| < 2.0`.
468+
this.get_exp().map(|v| v - 1).unwrap_or_else(|| {
469+
if this.is_infinite() {
470+
i32::MAX
471+
} else {
472+
// Zero or NaN
473+
i32::MIN
474+
}
475+
})
476+
}
477+
}
469478
}
470479
};
471480
}

crates/libm-test/src/test_traits.rs

+12
Original file line numberDiff line numberDiff line change
@@ -384,3 +384,15 @@ impl_tuples!(
384384
(f32, f32);
385385
(f64, f64);
386386
);
387+
388+
#[cfg(f16_enabled)]
389+
impl_tuples!(
390+
(f16, i32);
391+
(f16, f16);
392+
);
393+
394+
#[cfg(f128_enabled)]
395+
impl_tuples!(
396+
(f128, i32);
397+
(f128, f128);
398+
);

crates/libm-test/tests/compare_built_musl.rs

+4
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,10 @@ libm_macros::for_each_function! {
9595
fminf16,
9696
fmodf128,
9797
fmodf16,
98+
frexpf128,
99+
frexpf16,
100+
ilogbf128,
101+
ilogbf16,
98102
rintf128,
99103
rintf16,
100104
roundf128,

crates/util/src/main.rs

+4
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,10 @@ fn do_eval(basis: &str, op: &str, inputs: &[&str]) {
102102
| fminf16
103103
| fmodf128
104104
| fmodf16
105+
| frexpf128
106+
| frexpf16
107+
| ilogbf128
108+
| ilogbf16
105109
| rintf128
106110
| rintf16
107111
| roundf128

etc/function-definitions.json

+28
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,20 @@
478478
],
479479
"type": "f32"
480480
},
481+
"frexpf128": {
482+
"sources": [
483+
"src/math/frexpf128.rs",
484+
"src/math/generic/frexp.rs"
485+
],
486+
"type": "f128"
487+
},
488+
"frexpf16": {
489+
"sources": [
490+
"src/math/frexpf16.rs",
491+
"src/math/generic/frexp.rs"
492+
],
493+
"type": "f16"
494+
},
481495
"hypot": {
482496
"sources": [
483497
"src/libm_helper.rs",
@@ -506,6 +520,20 @@
506520
],
507521
"type": "f32"
508522
},
523+
"ilogbf128": {
524+
"sources": [
525+
"src/math/generic/ilogb.rs",
526+
"src/math/ilogbf128.rs"
527+
],
528+
"type": "f128"
529+
},
530+
"ilogbf16": {
531+
"sources": [
532+
"src/math/generic/ilogb.rs",
533+
"src/math/ilogbf16.rs"
534+
],
535+
"type": "f16"
536+
},
509537
"j0": {
510538
"sources": [
511539
"src/libm_helper.rs",

etc/function-list.txt

+4
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,14 @@ fmodf128
6767
fmodf16
6868
frexp
6969
frexpf
70+
frexpf128
71+
frexpf16
7072
hypot
7173
hypotf
7274
ilogb
7375
ilogbf
76+
ilogbf128
77+
ilogbf16
7478
j0
7579
j0f
7680
j1

src/math/frexpf128.rs

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
/// Decompose a float into a normalized value within the range `[0.5, 1)`, and a power of 2.
2+
///
3+
/// That is, `x * 2^p` will represent the input value.
4+
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
5+
pub fn frexpf128(x: f128) -> (f128, i32) {
6+
super::generic::frexp(x)
7+
}

src/math/frexpf16.rs

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
/// Decompose a float into a normalized value within the range `[0.5, 1)`, and a power of 2.
2+
///
3+
/// That is, `x * 2^p` will represent the input value.
4+
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
5+
pub fn frexpf16(x: f16) -> (f16, i32) {
6+
super::generic::frexp(x)
7+
}

src/math/ilogbf128.rs

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
/// Extract the binary exponent of `x`.
2+
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
3+
pub fn ilogbf128(x: f128) -> i32 {
4+
super::generic::ilogb(x)
5+
}

src/math/ilogbf16.rs

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
/// Extract the binary exponent of `x`.
2+
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
3+
pub fn ilogbf16(x: f16) -> i32 {
4+
super::generic::ilogb(x)
5+
}

src/math/mod.rs

+8
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,8 @@ cfg_if! {
349349
mod fmaxf16;
350350
mod fminf16;
351351
mod fmodf16;
352+
mod frexpf16;
353+
mod ilogbf16;
352354
mod rintf16;
353355
mod roundf16;
354356
mod sqrtf16;
@@ -362,6 +364,8 @@ cfg_if! {
362364
pub use self::fmaxf16::fmaxf16;
363365
pub use self::fminf16::fminf16;
364366
pub use self::fmodf16::fmodf16;
367+
pub use self::frexpf16::frexpf16;
368+
pub use self::ilogbf16::ilogbf16;
365369
pub use self::rintf16::rintf16;
366370
pub use self::roundf16::roundf16;
367371
pub use self::sqrtf16::sqrtf16;
@@ -379,6 +383,8 @@ cfg_if! {
379383
mod fmaxf128;
380384
mod fminf128;
381385
mod fmodf128;
386+
mod frexpf128;
387+
mod ilogbf128;
382388
mod rintf128;
383389
mod roundf128;
384390
mod sqrtf128;
@@ -392,6 +398,8 @@ cfg_if! {
392398
pub use self::fmaxf128::fmaxf128;
393399
pub use self::fminf128::fminf128;
394400
pub use self::fmodf128::fmodf128;
401+
pub use self::frexpf128::frexpf128;
402+
pub use self::ilogbf128::ilogbf128;
395403
pub use self::rintf128::rintf128;
396404
pub use self::roundf128::roundf128;
397405
pub use self::sqrtf128::sqrtf128;

0 commit comments

Comments
 (0)