math: Implement math.nextafter

This commit is contained in:
Dong-hee Na
2020-01-12 22:12:07 +09:00
parent 24289964d3
commit 1de9b1a41d
2 changed files with 33 additions and 0 deletions

View File

@@ -240,6 +240,19 @@ assert math.factorial(10) == 3628800
assert math.factorial(20) == 2432902008176640000
assert_raises(ValueError, lambda: math.factorial(-1))
if hasattr(math, 'nextafter'):
try:
assert math.nextafter(4503599627370496.0, -INF) == 4503599627370495.5
assert math.nextafter(4503599627370496.0, INF) == 4503599627370497.0
assert math.nextafter(9223372036854775808.0, 0.0) == 9223372036854774784.0
assert math.nextafter(-9223372036854775808.0, 0.0) == -9223372036854774784.0
assert math.nextafter(4503599627370496, -INF) == 4503599627370495.5
assert math.nextafter(2.0, 2.0) == 2.0
assert math.isnan(math.nextafter(NAN, 1.0))
except NotImplementedError:
# WASM
pass
assert math.modf(1.25) == (0.25, 1.0)
assert math.modf(-1.25) == (-0.25, -1.0)
assert math.modf(2.56) == (0.56, 2.0)

View File

@@ -17,6 +17,9 @@ use crate::obj::objtype;
use crate::pyobject::{PyObjectRef, PyResult, TypeProtocol};
use crate::vm::VirtualMachine;
#[cfg(not(target_arch = "wasm32"))]
use libc::c_double;
use std::cmp::Ordering;
// Helper macro:
@@ -291,6 +294,21 @@ fn math_modf(x: IntoPyFloat, _vm: &VirtualMachine) -> (f64, f64) {
(x.fract(), x.trunc())
}
#[cfg(not(target_arch = "wasm32"))]
fn math_nextafter(x: IntoPyFloat, y: IntoPyFloat) -> PyResult<f64> {
extern "C" {
fn nextafter(x: c_double, y: c_double) -> c_double;
}
let x = x.to_f64();
let y = y.to_f64();
Ok(unsafe { nextafter(x, y) })
}
#[cfg(target_arch = "wasm32")]
fn math_nextafter(x: IntoPyFloat, y: IntoPyFloat, vm: &VirtualMachine) -> PyResult<f64> {
Err(vm.new_not_implemented_error("not implemented for this platform".to_string()))
}
fn fmod(x: f64, y: f64) -> f64 {
if y.is_infinite() && x.is_finite() {
return x;
@@ -415,6 +433,8 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
// Factorial function
"factorial" => ctx.new_rustfunc(math_factorial),
"nextafter" => ctx.new_rustfunc(math_nextafter),
// Constants:
"pi" => ctx.new_float(std::f64::consts::PI), // 3.14159...
"e" => ctx.new_float(std::f64::consts::E), // 2.71..