Skip to content

Commit c4d1ad3

Browse files
authored
Merge pull request RustPython#1679 from corona10/math_nextafter
math: Implement math.nextafter
2 parents 86c098b + 1de9b1a commit c4d1ad3

File tree

2 files changed

+33
-0
lines changed

2 files changed

+33
-0
lines changed

tests/snippets/stdlib_math.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,19 @@ def assertAllNotClose(examples, *args, **kwargs):
240240
assert math.factorial(20) == 2432902008176640000
241241
assert_raises(ValueError, lambda: math.factorial(-1))
242242

243+
if hasattr(math, 'nextafter'):
244+
try:
245+
assert math.nextafter(4503599627370496.0, -INF) == 4503599627370495.5
246+
assert math.nextafter(4503599627370496.0, INF) == 4503599627370497.0
247+
assert math.nextafter(9223372036854775808.0, 0.0) == 9223372036854774784.0
248+
assert math.nextafter(-9223372036854775808.0, 0.0) == -9223372036854774784.0
249+
assert math.nextafter(4503599627370496, -INF) == 4503599627370495.5
250+
assert math.nextafter(2.0, 2.0) == 2.0
251+
assert math.isnan(math.nextafter(NAN, 1.0))
252+
except NotImplementedError:
253+
# WASM
254+
pass
255+
243256
assert math.modf(1.25) == (0.25, 1.0)
244257
assert math.modf(-1.25) == (-0.25, -1.0)
245258
assert math.modf(2.56) == (0.56, 2.0)

vm/src/stdlib/math.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ use crate::obj::objtype;
1717
use crate::pyobject::{PyObjectRef, PyResult, TypeProtocol};
1818
use crate::vm::VirtualMachine;
1919

20+
#[cfg(not(target_arch = "wasm32"))]
21+
use libc::c_double;
22+
2023
use std::cmp::Ordering;
2124

2225
// Helper macro:
@@ -291,6 +294,21 @@ fn math_modf(x: IntoPyFloat, _vm: &VirtualMachine) -> (f64, f64) {
291294
(x.fract(), x.trunc())
292295
}
293296

297+
#[cfg(not(target_arch = "wasm32"))]
298+
fn math_nextafter(x: IntoPyFloat, y: IntoPyFloat) -> PyResult<f64> {
299+
extern "C" {
300+
fn nextafter(x: c_double, y: c_double) -> c_double;
301+
}
302+
let x = x.to_f64();
303+
let y = y.to_f64();
304+
Ok(unsafe { nextafter(x, y) })
305+
}
306+
307+
#[cfg(target_arch = "wasm32")]
308+
fn math_nextafter(x: IntoPyFloat, y: IntoPyFloat, vm: &VirtualMachine) -> PyResult<f64> {
309+
Err(vm.new_not_implemented_error("not implemented for this platform".to_string()))
310+
}
311+
294312
fn fmod(x: f64, y: f64) -> f64 {
295313
if y.is_infinite() && x.is_finite() {
296314
return x;
@@ -415,6 +433,8 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
415433
// Factorial function
416434
"factorial" => ctx.new_function(math_factorial),
417435

436+
"nextafter" => ctx.new_rustfunc(math_nextafter),
437+
418438
// Constants:
419439
"pi" => ctx.new_float(std::f64::consts::PI), // 3.14159...
420440
"e" => ctx.new_float(std::f64::consts::E), // 2.71..

0 commit comments

Comments
 (0)