From 533aa2bc260d99b17bd0c3e71d44c6cfa0f8dada Mon Sep 17 00:00:00 2001 From: "johan.park" Date: Sat, 19 Oct 2019 14:34:45 +0900 Subject: [PATCH] Update fmod module of math - Implement fmod function with test case --- tests/snippets/stdlib_math.py | 20 ++++++++++++++++++++ vm/src/stdlib/math.rs | 15 +++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/tests/snippets/stdlib_math.py b/tests/snippets/stdlib_math.py index bc72dce85..6a5a37e11 100644 --- a/tests/snippets/stdlib_math.py +++ b/tests/snippets/stdlib_math.py @@ -246,3 +246,23 @@ assert math.modf(NINF) == (-0.0, NINF) modf_nan = math.modf(NAN) assert math.isnan(modf_nan[0]) assert math.isnan(modf_nan[1]) + +assert math.fmod(10, 1) == 0.0 +assert math.fmod(10, 0.5) == 0.0 +assert math.fmod(10, 1.5) == 1.0 +assert math.fmod(-10, 1) == -0.0 +assert math.fmod(-10, 0.5) == -0.0 +assert math.fmod(-10, 1.5) == -1.0 +assert math.isnan(math.fmod(NAN, 1.)) == True +assert math.isnan(math.fmod(1., NAN)) == True +assert math.isnan(math.fmod(NAN, NAN)) == True +assert_raises(ValueError, lambda: math.fmod(1., 0.)) +assert_raises(ValueError, lambda: math.fmod(INF, 1.)) +assert_raises(ValueError, lambda: math.fmod(NINF, 1.)) +assert_raises(ValueError, lambda: math.fmod(INF, 0.)) +assert math.fmod(3.0, INF) == 3.0 +assert math.fmod(-3.0, INF) == -3.0 +assert math.fmod(3.0, NINF) == 3.0 +assert math.fmod(-3.0, NINF) == -3.0 +assert math.fmod(0.0, 3.0) == 0.0 +assert math.fmod(0.0, NINF) == 0.0 \ No newline at end of file diff --git a/vm/src/stdlib/math.rs b/vm/src/stdlib/math.rs index e63f6b2c1..47116207d 100644 --- a/vm/src/stdlib/math.rs +++ b/vm/src/stdlib/math.rs @@ -275,6 +275,20 @@ fn math_modf(x: IntoPyFloat, _vm: &VirtualMachine) -> (f64, f64) { (x.fract(), x.trunc()) } +fn math_fmod(x: IntoPyFloat, y: IntoPyFloat, vm: &VirtualMachine) -> PyResult { + let x = x.to_f64(); + let y = y.to_f64(); + if y.is_infinite() && x.is_finite() { + return Ok(x); + } + let r = x % y; + if r.is_nan() && !x.is_nan() && !y.is_nan() { + return Err(vm.new_value_error("math domain error".to_string())); + } + + Ok(r) +} + pub fn make_module(vm: &VirtualMachine) -> PyObjectRef { let ctx = &vm.ctx; @@ -327,6 +341,7 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef { "frexp" => ctx.new_rustfunc(math_frexp), "ldexp" => ctx.new_rustfunc(math_ldexp), "modf" => ctx.new_rustfunc(math_modf), + "fmod" => ctx.new_rustfunc(math_fmod), // Rounding functions: "trunc" => ctx.new_rustfunc(math_trunc),