From 1de9b1a41d2478b28c37d48ec188a939e0945c43 Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Sun, 12 Jan 2020 22:12:07 +0900 Subject: [PATCH] math: Implement math.nextafter --- tests/snippets/stdlib_math.py | 13 +++++++++++++ vm/src/stdlib/math.rs | 20 ++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/tests/snippets/stdlib_math.py b/tests/snippets/stdlib_math.py index 13e230e67a..2c21390619 100644 --- a/tests/snippets/stdlib_math.py +++ b/tests/snippets/stdlib_math.py @@ -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) diff --git a/vm/src/stdlib/math.rs b/vm/src/stdlib/math.rs index d875d9ba1a..b3df1b9068 100644 --- a/vm/src/stdlib/math.rs +++ b/vm/src/stdlib/math.rs @@ -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 { + 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 { + 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..