diff options
| author | cremno <[email protected]> | 2014-05-02 21:58:29 +0200 |
|---|---|---|
| committer | cremno <[email protected]> | 2014-05-02 23:48:25 +0200 |
| commit | 405e8fbcd50b1827618ef6cc286e861a8bacd163 (patch) | |
| tree | ee0ff5ffcdeba913f775ed59fd32795a6bd836c6 /mrbgems/mruby-math | |
| parent | 72fe54c40316acff40f7748e447db9e7bc73849d (diff) | |
| download | mruby-405e8fbcd50b1827618ef6cc286e861a8bacd163.tar.gz mruby-405e8fbcd50b1827618ef6cc286e861a8bacd163.zip | |
mruby-math: define and use `Math::DomainError`
Domain errors are detected as per ISO C99 and may differ from CRuby.
Diffstat (limited to 'mrbgems/mruby-math')
| -rw-r--r-- | mrbgems/mruby-math/src/math.c | 39 |
1 files changed, 37 insertions, 2 deletions
diff --git a/mrbgems/mruby-math/src/math.c b/mrbgems/mruby-math/src/math.c index a699a12f0..871cba301 100644 --- a/mrbgems/mruby-math/src/math.c +++ b/mrbgems/mruby-math/src/math.c @@ -9,8 +9,14 @@ #include <math.h> -#define domain_error(msg) \ - mrb_raise(mrb, E_RANGE_ERROR, "Numerical argument is out of domain - " #msg) +static void +domain_error(mrb_state *mrb, const char *func) +{ + struct RClass *math = mrb_module_get(mrb, "Math"); + struct RClass *domainerror = mrb_class_get_under(mrb, math, "DomainError"); + mrb_value str = mrb_str_new_cstr(mrb, func); + mrb_raisef(mrb, domainerror, "Numerical argument is out of domain - %S", str); +} /* math functions not provided by Microsoft Visual C++ 2012 or older */ #if defined _MSC_VER && _MSC_VER < 1800 @@ -172,6 +178,9 @@ math_asin(mrb_state *mrb, mrb_value obj) mrb_float x; mrb_get_args(mrb, "f", &x); + if (x < -1.0 || x > 1.0) { + domain_error(mrb, "asin"); + } x = asin(x); return mrb_float_value(mrb, x); @@ -189,6 +198,9 @@ math_acos(mrb_state *mrb, mrb_value obj) mrb_float x; mrb_get_args(mrb, "f", &x); + if (x < -1.0 || x > 1.0) { + domain_error(mrb, "acos"); + } x = acos(x); return mrb_float_value(mrb, x); @@ -334,6 +346,9 @@ math_acosh(mrb_state *mrb, mrb_value obj) mrb_float x; mrb_get_args(mrb, "f", &x); + if (x < 1.0) { + domain_error(mrb, "acosh"); + } x = acosh(x); return mrb_float_value(mrb, x); @@ -351,6 +366,9 @@ math_atanh(mrb_state *mrb, mrb_value obj) mrb_float x; mrb_get_args(mrb, "f", &x); + if (x < -1.0 || x > 1.0) { + domain_error(mrb, "atanh"); + } x = atanh(x); return mrb_float_value(mrb, x); @@ -404,8 +422,14 @@ math_log(mrb_state *mrb, mrb_value obj) int argc; argc = mrb_get_args(mrb, "f|f", &x, &base); + if (x < 0.0) { + domain_error(mrb, "log"); + } x = log(x); if (argc == 2) { + if (base < 0.0) { + domain_error(mrb, "log"); + } x /= log(base); } return mrb_float_value(mrb, x); @@ -429,6 +453,9 @@ math_log2(mrb_state *mrb, mrb_value obj) mrb_float x; mrb_get_args(mrb, "f", &x); + if (x < 0.0) { + domain_error(mrb, "log2"); + } x = log2(x); return mrb_float_value(mrb, x); @@ -451,6 +478,9 @@ math_log10(mrb_state *mrb, mrb_value obj) mrb_float x; mrb_get_args(mrb, "f", &x); + if (x < 0.0) { + domain_error(mrb, "log10"); + } x = log10(x); return mrb_float_value(mrb, x); @@ -469,6 +499,9 @@ math_sqrt(mrb_state *mrb, mrb_value obj) mrb_float x; mrb_get_args(mrb, "f", &x); + if (x < 0.0) { + domain_error(mrb, "sqrt"); + } x = sqrt(x); return mrb_float_value(mrb, x); @@ -624,6 +657,8 @@ mrb_mruby_math_gem_init(mrb_state* mrb) struct RClass *mrb_math; mrb_math = mrb_define_module(mrb, "Math"); + mrb_define_class_under(mrb, mrb_math, "DomainError", mrb->eStandardError_class); + #ifdef M_PI mrb_define_const(mrb, mrb_math, "PI", mrb_float_value(mrb, M_PI)); #else |
