support and test some more math functions
This commit is contained in:
parent
5a4ac1ebf0
commit
b1316eca92
@ -575,15 +575,18 @@ fn emulate_foreign_item_by_name(
|
|||||||
this.write_scalar(Scalar::from_machine_usize(u64::try_from(n).unwrap(), this), dest)?;
|
this.write_scalar(Scalar::from_machine_usize(u64::try_from(n).unwrap(), this), dest)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// math functions
|
// math functions (note that there are also intrinsics for some other functions)
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
| "cbrtf"
|
| "cbrtf"
|
||||||
| "coshf"
|
| "coshf"
|
||||||
| "sinhf"
|
| "sinhf"
|
||||||
| "tanf"
|
| "tanf"
|
||||||
|
| "tanhf"
|
||||||
| "acosf"
|
| "acosf"
|
||||||
| "asinf"
|
| "asinf"
|
||||||
| "atanf"
|
| "atanf"
|
||||||
|
| "log1pf"
|
||||||
|
| "expm1f"
|
||||||
=> {
|
=> {
|
||||||
let [f] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
let [f] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||||
// FIXME: Using host floats.
|
// FIXME: Using host floats.
|
||||||
@ -593,9 +596,12 @@ fn emulate_foreign_item_by_name(
|
|||||||
"coshf" => f.cosh(),
|
"coshf" => f.cosh(),
|
||||||
"sinhf" => f.sinh(),
|
"sinhf" => f.sinh(),
|
||||||
"tanf" => f.tan(),
|
"tanf" => f.tan(),
|
||||||
|
"tanhf" => f.tanh(),
|
||||||
"acosf" => f.acos(),
|
"acosf" => f.acos(),
|
||||||
"asinf" => f.asin(),
|
"asinf" => f.asin(),
|
||||||
"atanf" => f.atan(),
|
"atanf" => f.atan(),
|
||||||
|
"log1pf" => f.ln_1p(),
|
||||||
|
"expm1f" => f.exp_m1(),
|
||||||
_ => bug!(),
|
_ => bug!(),
|
||||||
};
|
};
|
||||||
this.write_scalar(Scalar::from_u32(res.to_bits()), dest)?;
|
this.write_scalar(Scalar::from_u32(res.to_bits()), dest)?;
|
||||||
@ -604,6 +610,7 @@ fn emulate_foreign_item_by_name(
|
|||||||
| "_hypotf"
|
| "_hypotf"
|
||||||
| "hypotf"
|
| "hypotf"
|
||||||
| "atan2f"
|
| "atan2f"
|
||||||
|
| "fdimf"
|
||||||
=> {
|
=> {
|
||||||
let [f1, f2] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
let [f1, f2] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||||
// underscore case for windows, here and below
|
// underscore case for windows, here and below
|
||||||
@ -614,6 +621,8 @@ fn emulate_foreign_item_by_name(
|
|||||||
let res = match link_name.as_str() {
|
let res = match link_name.as_str() {
|
||||||
"_hypotf" | "hypotf" => f1.hypot(f2),
|
"_hypotf" | "hypotf" => f1.hypot(f2),
|
||||||
"atan2f" => f1.atan2(f2),
|
"atan2f" => f1.atan2(f2),
|
||||||
|
#[allow(deprecated)]
|
||||||
|
"fdimf" => f1.abs_sub(f2),
|
||||||
_ => bug!(),
|
_ => bug!(),
|
||||||
};
|
};
|
||||||
this.write_scalar(Scalar::from_u32(res.to_bits()), dest)?;
|
this.write_scalar(Scalar::from_u32(res.to_bits()), dest)?;
|
||||||
@ -623,9 +632,12 @@ fn emulate_foreign_item_by_name(
|
|||||||
| "cosh"
|
| "cosh"
|
||||||
| "sinh"
|
| "sinh"
|
||||||
| "tan"
|
| "tan"
|
||||||
|
| "tanh"
|
||||||
| "acos"
|
| "acos"
|
||||||
| "asin"
|
| "asin"
|
||||||
| "atan"
|
| "atan"
|
||||||
|
| "log1p"
|
||||||
|
| "expm1"
|
||||||
=> {
|
=> {
|
||||||
let [f] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
let [f] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||||
// FIXME: Using host floats.
|
// FIXME: Using host floats.
|
||||||
@ -635,9 +647,12 @@ fn emulate_foreign_item_by_name(
|
|||||||
"cosh" => f.cosh(),
|
"cosh" => f.cosh(),
|
||||||
"sinh" => f.sinh(),
|
"sinh" => f.sinh(),
|
||||||
"tan" => f.tan(),
|
"tan" => f.tan(),
|
||||||
|
"tanh" => f.tanh(),
|
||||||
"acos" => f.acos(),
|
"acos" => f.acos(),
|
||||||
"asin" => f.asin(),
|
"asin" => f.asin(),
|
||||||
"atan" => f.atan(),
|
"atan" => f.atan(),
|
||||||
|
"log1p" => f.ln_1p(),
|
||||||
|
"expm1" => f.exp_m1(),
|
||||||
_ => bug!(),
|
_ => bug!(),
|
||||||
};
|
};
|
||||||
this.write_scalar(Scalar::from_u64(res.to_bits()), dest)?;
|
this.write_scalar(Scalar::from_u64(res.to_bits()), dest)?;
|
||||||
@ -646,6 +661,7 @@ fn emulate_foreign_item_by_name(
|
|||||||
| "_hypot"
|
| "_hypot"
|
||||||
| "hypot"
|
| "hypot"
|
||||||
| "atan2"
|
| "atan2"
|
||||||
|
| "fdim"
|
||||||
=> {
|
=> {
|
||||||
let [f1, f2] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
let [f1, f2] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||||
// FIXME: Using host floats.
|
// FIXME: Using host floats.
|
||||||
@ -654,6 +670,8 @@ fn emulate_foreign_item_by_name(
|
|||||||
let res = match link_name.as_str() {
|
let res = match link_name.as_str() {
|
||||||
"_hypot" | "hypot" => f1.hypot(f2),
|
"_hypot" | "hypot" => f1.hypot(f2),
|
||||||
"atan2" => f1.atan2(f2),
|
"atan2" => f1.atan2(f2),
|
||||||
|
#[allow(deprecated)]
|
||||||
|
"fdim" => f1.abs_sub(f2),
|
||||||
_ => bug!(),
|
_ => bug!(),
|
||||||
};
|
};
|
||||||
this.write_scalar(Scalar::from_u64(res.to_bits()), dest)?;
|
this.write_scalar(Scalar::from_u64(res.to_bits()), dest)?;
|
||||||
|
@ -32,24 +32,24 @@ pub fn main() {
|
|||||||
assert_approx_eq!(25f32.powi(-2), 0.0016f32);
|
assert_approx_eq!(25f32.powi(-2), 0.0016f32);
|
||||||
assert_approx_eq!(23.2f64.powi(2), 538.24f64);
|
assert_approx_eq!(23.2f64.powi(2), 538.24f64);
|
||||||
|
|
||||||
assert_approx_eq!(0f32.sin(), 0f32);
|
|
||||||
assert_approx_eq!((f64::consts::PI / 2f64).sin(), 1f64);
|
|
||||||
|
|
||||||
assert_approx_eq!(0f32.cos(), 1f32);
|
|
||||||
assert_approx_eq!((f64::consts::PI * 2f64).cos(), 1f64);
|
|
||||||
|
|
||||||
assert_approx_eq!(25f32.powf(-2f32), 0.0016f32);
|
assert_approx_eq!(25f32.powf(-2f32), 0.0016f32);
|
||||||
assert_approx_eq!(400f64.powf(0.5f64), 20f64);
|
assert_approx_eq!(400f64.powf(0.5f64), 20f64);
|
||||||
|
|
||||||
assert_approx_eq!((1f32.exp() - f32::consts::E).abs(), 0f32);
|
assert_approx_eq!(1f32.exp(), f32::consts::E);
|
||||||
assert_approx_eq!(1f64.exp(), f64::consts::E);
|
assert_approx_eq!(1f64.exp(), f64::consts::E);
|
||||||
|
|
||||||
|
assert_approx_eq!(1f32.exp_m1(), f32::consts::E - 1.0);
|
||||||
|
assert_approx_eq!(1f64.exp_m1(), f64::consts::E - 1.0);
|
||||||
|
|
||||||
assert_approx_eq!(10f32.exp2(), 1024f32);
|
assert_approx_eq!(10f32.exp2(), 1024f32);
|
||||||
assert_approx_eq!(50f64.exp2(), 1125899906842624f64);
|
assert_approx_eq!(50f64.exp2(), 1125899906842624f64);
|
||||||
|
|
||||||
assert_approx_eq!((f32::consts::E.ln() - 1f32).abs(), 0f32);
|
assert_approx_eq!(f32::consts::E.ln(), 1f32);
|
||||||
assert_approx_eq!(1f64.ln(), 0f64);
|
assert_approx_eq!(1f64.ln(), 0f64);
|
||||||
|
|
||||||
|
assert_approx_eq!(0f32.ln_1p(), 0f32);
|
||||||
|
assert_approx_eq!(0f64.ln_1p(), 0f64);
|
||||||
|
|
||||||
assert_approx_eq!(10f32.log10(), 1f32);
|
assert_approx_eq!(10f32.log10(), 1f32);
|
||||||
assert_approx_eq!(f64::consts::E.log10(), f64::consts::LOG10_E);
|
assert_approx_eq!(f64::consts::E.log10(), f64::consts::LOG10_E);
|
||||||
|
|
||||||
@ -66,6 +66,12 @@ pub fn main() {
|
|||||||
assert_approx_eq!((-1.0f32).abs(), 1.0f32);
|
assert_approx_eq!((-1.0f32).abs(), 1.0f32);
|
||||||
assert_approx_eq!(34.2f64.abs(), 34.2f64);
|
assert_approx_eq!(34.2f64.abs(), 34.2f64);
|
||||||
|
|
||||||
|
#[allow(deprecated)]
|
||||||
|
{
|
||||||
|
assert_approx_eq!(5.0f32.abs_sub(3.0), 2.0);
|
||||||
|
assert_approx_eq!(3.0f64.abs_sub(5.0), 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
assert_approx_eq!(3.8f32.floor(), 3.0f32);
|
assert_approx_eq!(3.8f32.floor(), 3.0f32);
|
||||||
assert_approx_eq!((-1.1f64).floor(), -2.0f64);
|
assert_approx_eq!((-1.1f64).floor(), -2.0f64);
|
||||||
|
|
||||||
@ -81,31 +87,54 @@ pub fn main() {
|
|||||||
assert_approx_eq!(3.0f32.hypot(4.0f32), 5.0f32);
|
assert_approx_eq!(3.0f32.hypot(4.0f32), 5.0f32);
|
||||||
assert_approx_eq!(3.0f64.hypot(4.0f64), 5.0f64);
|
assert_approx_eq!(3.0f64.hypot(4.0f64), 5.0f64);
|
||||||
|
|
||||||
assert_approx_eq!(1.0f32.atan2(2.0f32), 0.46364761f32);
|
|
||||||
assert_approx_eq!(1.0f32.atan2(2.0f32), 0.46364761f32);
|
|
||||||
|
|
||||||
assert_approx_eq!(1.0f32.cosh(), 1.54308f32);
|
|
||||||
assert_approx_eq!(1.0f64.cosh(), 1.54308f64);
|
|
||||||
|
|
||||||
assert_approx_eq!(1.0f32.sinh(), 1.1752012f32);
|
|
||||||
assert_approx_eq!(1.0f64.sinh(), 1.1752012f64);
|
|
||||||
|
|
||||||
assert_approx_eq!(1.0f32.tan(), 1.557408f32);
|
|
||||||
assert_approx_eq!(1.0f64.tan(), 1.557408f64);
|
|
||||||
|
|
||||||
assert_approx_eq!(f32::consts::FRAC_PI_4.cos().acos(), f32::consts::FRAC_PI_4);
|
|
||||||
assert_approx_eq!(f64::consts::FRAC_PI_4.cos().acos(), f64::consts::FRAC_PI_4);
|
|
||||||
|
|
||||||
assert_approx_eq!(f32::consts::FRAC_PI_4.sin().asin(), f32::consts::FRAC_PI_4);
|
|
||||||
assert_approx_eq!(f64::consts::FRAC_PI_4.sin().asin(), f64::consts::FRAC_PI_4);
|
|
||||||
|
|
||||||
assert_approx_eq!(1.0_f32, 1.0_f32.tan().atan());
|
|
||||||
assert_approx_eq!(1.0_f64, 1.0_f64.tan().atan());
|
|
||||||
|
|
||||||
assert_eq!(3.3_f32.round(), 3.0);
|
assert_eq!(3.3_f32.round(), 3.0);
|
||||||
assert_eq!(3.3_f64.round(), 3.0);
|
assert_eq!(3.3_f64.round(), 3.0);
|
||||||
|
|
||||||
assert_eq!(ldexp(0.65f64, 3i32), 5.2f64);
|
assert_eq!(ldexp(0.65f64, 3i32), 5.2f64);
|
||||||
assert_eq!(ldexp(1.42, 0xFFFF), f64::INFINITY);
|
assert_eq!(ldexp(1.42, 0xFFFF), f64::INFINITY);
|
||||||
assert_eq!(ldexp(1.42, -0xFFFF), 0f64);
|
assert_eq!(ldexp(1.42, -0xFFFF), 0f64);
|
||||||
|
|
||||||
|
// Trigonometric functions.
|
||||||
|
|
||||||
|
assert_approx_eq!(0f32.sin(), 0f32);
|
||||||
|
assert_approx_eq!((f64::consts::PI / 2f64).sin(), 1f64);
|
||||||
|
assert_approx_eq!(f32::consts::FRAC_PI_6.sin(), 0.5);
|
||||||
|
assert_approx_eq!(f64::consts::FRAC_PI_6.sin(), 0.5);
|
||||||
|
assert_approx_eq!(f32::consts::FRAC_PI_4.sin().asin(), f32::consts::FRAC_PI_4);
|
||||||
|
assert_approx_eq!(f64::consts::FRAC_PI_4.sin().asin(), f64::consts::FRAC_PI_4);
|
||||||
|
|
||||||
|
assert_approx_eq!(1.0f32.sinh(), 1.1752012f32);
|
||||||
|
assert_approx_eq!(1.0f64.sinh(), 1.1752012f64);
|
||||||
|
assert_approx_eq!(2.0f32.asinh(), 1.443635475178810342493276740273105f32);
|
||||||
|
assert_approx_eq!((-2.0f64).asinh(), -1.443635475178810342493276740273105f64);
|
||||||
|
|
||||||
|
assert_approx_eq!(0f32.cos(), 1f32);
|
||||||
|
assert_approx_eq!((f64::consts::PI * 2f64).cos(), 1f64);
|
||||||
|
assert_approx_eq!(f32::consts::FRAC_PI_3.cos(), 0.5);
|
||||||
|
assert_approx_eq!(f64::consts::FRAC_PI_3.cos(), 0.5);
|
||||||
|
assert_approx_eq!(f32::consts::FRAC_PI_4.cos().acos(), f32::consts::FRAC_PI_4);
|
||||||
|
assert_approx_eq!(f64::consts::FRAC_PI_4.cos().acos(), f64::consts::FRAC_PI_4);
|
||||||
|
|
||||||
|
assert_approx_eq!(1.0f32.cosh(), 1.54308f32);
|
||||||
|
assert_approx_eq!(1.0f64.cosh(), 1.54308f64);
|
||||||
|
assert_approx_eq!(2.0f32.acosh(), 1.31695789692481670862504634730796844f32);
|
||||||
|
assert_approx_eq!(3.0f64.acosh(), 1.76274717403908605046521864995958461f64);
|
||||||
|
|
||||||
|
assert_approx_eq!(1.0f32.tan(), 1.557408f32);
|
||||||
|
assert_approx_eq!(1.0f64.tan(), 1.557408f64);
|
||||||
|
assert_approx_eq!(1.0_f32, 1.0_f32.tan().atan());
|
||||||
|
assert_approx_eq!(1.0_f64, 1.0_f64.tan().atan());
|
||||||
|
assert_approx_eq!(1.0f32.atan2(2.0f32), 0.46364761f32);
|
||||||
|
assert_approx_eq!(1.0f32.atan2(2.0f32), 0.46364761f32);
|
||||||
|
|
||||||
|
assert_approx_eq!(
|
||||||
|
1.0f32.tanh(),
|
||||||
|
(1.0 - f32::consts::E.powi(-2)) / (1.0 + f32::consts::E.powi(-2))
|
||||||
|
);
|
||||||
|
assert_approx_eq!(
|
||||||
|
1.0f64.tanh(),
|
||||||
|
(1.0 - f64::consts::E.powi(-2)) / (1.0 + f64::consts::E.powi(-2))
|
||||||
|
);
|
||||||
|
assert_approx_eq!(0.5f32.atanh(), 0.54930614433405484569762261846126285f32);
|
||||||
|
assert_approx_eq!(0.5f64.atanh(), 0.54930614433405484569762261846126285f64);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user