Skip to content

Commit a6ceafd

Browse files
committed
Add frexpf16, frexpf128, ilogbf16, and ilogbf128
1 parent b17a955 commit a6ceafd

File tree

13 files changed

+163
-42
lines changed

13 files changed

+163
-42
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
@@ -131,6 +131,10 @@ libm_macros::for_each_function! {
131131
| fmaxf16
132132
| fminf128
133133
| fminf16
134+
| frexpf128
135+
| frexpf16
136+
| ilogbf128
137+
| ilogbf16
134138
| rintf128
135139
| rintf16
136140
| roundf128

crates/libm-test/src/mpfloat.rs

+47-42
Original file line numberDiff line numberDiff line change
@@ -154,8 +154,12 @@ libm_macros::for_each_function! {
154154
fmodf,
155155
frexp,
156156
frexpf,
157+
frexpf128,
158+
frexpf16,
157159
ilogb,
158160
ilogbf,
161+
ilogbf128,
162+
ilogbf16,
159163
jn,
160164
jnf,
161165
ldexp,
@@ -315,48 +319,6 @@ macro_rules! impl_op_for_ty {
315319
}
316320
}
317321

318-
impl MpOp for crate::op::[<frexp $suffix>]::Routine {
319-
type MpTy = MpFloat;
320-
321-
fn new_mp() -> Self::MpTy {
322-
new_mpfloat::<Self::FTy>()
323-
}
324-
325-
fn run(this: &mut Self::MpTy, input: Self::RustArgs) -> Self::RustRet {
326-
// Implementation taken from `rug::Float::to_f32_exp`.
327-
this.assign(input.0);
328-
let exp = this.get_exp().unwrap_or(0);
329-
if exp != 0 {
330-
*this >>= exp;
331-
}
332-
333-
(prep_retval::<Self::FTy>(this, Ordering::Equal), exp)
334-
}
335-
}
336-
337-
impl MpOp for crate::op::[<ilogb $suffix>]::Routine {
338-
type MpTy = MpFloat;
339-
340-
fn new_mp() -> Self::MpTy {
341-
new_mpfloat::<Self::FTy>()
342-
}
343-
344-
fn run(this: &mut Self::MpTy, input: Self::RustArgs) -> Self::RustRet {
345-
this.assign(input.0);
346-
347-
// `get_exp` follows `frexp` for `0.5 <= |m| < 1.0`. Adjust the exponent by
348-
// one to scale the significand to `1.0 <= |m| < 2.0`.
349-
this.get_exp().map(|v| v - 1).unwrap_or_else(|| {
350-
if this.is_infinite() {
351-
i32::MAX
352-
} else {
353-
// Zero or NaN
354-
i32::MIN
355-
}
356-
})
357-
}
358-
}
359-
360322
impl MpOp for crate::op::[<jn $suffix>]::Routine {
361323
type MpTy = MpFloat;
362324

@@ -480,6 +442,49 @@ macro_rules! impl_op_for_ty_all {
480442
prep_retval::<Self::RustRet>(&mut this.0, Ordering::Equal)
481443
}
482444
}
445+
446+
impl MpOp for crate::op::[<frexp $suffix>]::Routine {
447+
type MpTy = MpFloat;
448+
449+
fn new_mp() -> Self::MpTy {
450+
new_mpfloat::<Self::FTy>()
451+
}
452+
453+
fn run(this: &mut Self::MpTy, input: Self::RustArgs) -> Self::RustRet {
454+
// Implementation taken from `rug::Float::to_f32_exp`.
455+
this.assign(input.0);
456+
let exp = this.get_exp().unwrap_or(0);
457+
if exp != 0 {
458+
*this >>= exp;
459+
}
460+
461+
(prep_retval::<Self::FTy>(this, Ordering::Equal), exp)
462+
}
463+
}
464+
465+
impl MpOp for crate::op::[<ilogb $suffix>]::Routine {
466+
type MpTy = MpFloat;
467+
468+
fn new_mp() -> Self::MpTy {
469+
new_mpfloat::<Self::FTy>()
470+
}
471+
472+
fn run(this: &mut Self::MpTy, input: Self::RustArgs) -> Self::RustRet {
473+
this.assign(input.0);
474+
475+
// `get_exp` follows `frexp` for `0.5 <= |m| < 1.0`. Adjust the exponent by
476+
// one to scale the significand to `1.0 <= |m| < 2.0`.
477+
this.get_exp().map(|v| v - 1).unwrap_or_else(|| {
478+
if this.is_infinite() {
479+
i32::MAX
480+
} else {
481+
// Zero or NaN
482+
i32::MIN
483+
}
484+
})
485+
}
486+
}
487+
483488
}
484489
};
485490
}

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
@@ -93,6 +93,10 @@ libm_macros::for_each_function! {
9393
fmaxf16,
9494
fminf128,
9595
fminf16,
96+
frexpf128,
97+
frexpf16,
98+
ilogbf128,
99+
ilogbf16,
96100
rintf128,
97101
rintf16,
98102
roundf128,

crates/util/src/main.rs

+4
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,10 @@ fn do_eval(basis: &str, op: &str, inputs: &[&str]) {
100100
| fmaxf16
101101
| fminf128
102102
| fminf16
103+
| frexpf128
104+
| frexpf16
105+
| ilogbf128
106+
| ilogbf16
103107
| rintf128
104108
| rintf16
105109
| roundf128

etc/function-definitions.json

+28
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,20 @@
462462
],
463463
"type": "f32"
464464
},
465+
"frexpf128": {
466+
"sources": [
467+
"src/math/frexpf128.rs",
468+
"src/math/generic/frexp.rs"
469+
],
470+
"type": "f128"
471+
},
472+
"frexpf16": {
473+
"sources": [
474+
"src/math/frexpf16.rs",
475+
"src/math/generic/frexp.rs"
476+
],
477+
"type": "f16"
478+
},
465479
"hypot": {
466480
"sources": [
467481
"src/libm_helper.rs",
@@ -490,6 +504,20 @@
490504
],
491505
"type": "f32"
492506
},
507+
"ilogbf128": {
508+
"sources": [
509+
"src/math/generic/ilogb.rs",
510+
"src/math/ilogbf128.rs"
511+
],
512+
"type": "f128"
513+
},
514+
"ilogbf16": {
515+
"sources": [
516+
"src/math/generic/ilogb.rs",
517+
"src/math/ilogbf16.rs"
518+
],
519+
"type": "f16"
520+
},
493521
"j0": {
494522
"sources": [
495523
"src/libm_helper.rs",

etc/function-list.txt

+4
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,14 @@ fmod
6565
fmodf
6666
frexp
6767
frexpf
68+
frexpf128
69+
frexpf16
6870
hypot
6971
hypotf
7072
ilogb
7173
ilogbf
74+
ilogbf128
75+
ilogbf16
7276
j0
7377
j0f
7478
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
@@ -348,6 +348,8 @@ cfg_if! {
348348
mod floorf16;
349349
mod fmaxf16;
350350
mod fminf16;
351+
mod frexpf16;
352+
mod ilogbf16;
351353
mod rintf16;
352354
mod roundf16;
353355
mod sqrtf16;
@@ -360,6 +362,8 @@ cfg_if! {
360362
pub use self::floorf16::floorf16;
361363
pub use self::fmaxf16::fmaxf16;
362364
pub use self::fminf16::fminf16;
365+
pub use self::frexpf16::frexpf16;
366+
pub use self::ilogbf16::ilogbf16;
363367
pub use self::rintf16::rintf16;
364368
pub use self::roundf16::roundf16;
365369
pub use self::sqrtf16::sqrtf16;
@@ -376,6 +380,8 @@ cfg_if! {
376380
mod floorf128;
377381
mod fmaxf128;
378382
mod fminf128;
383+
mod frexpf128;
384+
mod ilogbf128;
379385
mod rintf128;
380386
mod roundf128;
381387
mod sqrtf128;
@@ -388,6 +394,8 @@ cfg_if! {
388394
pub use self::floorf128::floorf128;
389395
pub use self::fmaxf128::fmaxf128;
390396
pub use self::fminf128::fminf128;
397+
pub use self::frexpf128::frexpf128;
398+
pub use self::ilogbf128::ilogbf128;
391399
pub use self::rintf128::rintf128;
392400
pub use self::roundf128::roundf128;
393401
pub use self::sqrtf128::sqrtf128;

0 commit comments

Comments
 (0)