00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "ruby.h"
00014 #include <math.h>
00015 #include <errno.h>
00016
00017 VALUE rb_mMath;
00018
00019 #define Need_Float(x) (x) = rb_Float(x)
00020 #define Need_Float2(x,y) do {\
00021 Need_Float(x);\
00022 Need_Float(y);\
00023 } while (0)
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 static VALUE
00036 math_atan2(obj, y, x)
00037 VALUE obj, x, y;
00038 {
00039 Need_Float2(y, x);
00040 return rb_float_new(atan2(RFLOAT(y)->value, RFLOAT(x)->value));
00041 }
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053 static VALUE
00054 math_cos(obj, x)
00055 VALUE obj, x;
00056 {
00057 Need_Float(x);
00058 return rb_float_new(cos(RFLOAT(x)->value));
00059 }
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069 static VALUE
00070 math_sin(obj, x)
00071 VALUE obj, x;
00072 {
00073 Need_Float(x);
00074
00075 return rb_float_new(sin(RFLOAT(x)->value));
00076 }
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086 static VALUE
00087 math_tan(obj, x)
00088 VALUE obj, x;
00089 {
00090 Need_Float(x);
00091
00092 return rb_float_new(tan(RFLOAT(x)->value));
00093 }
00094
00095
00096
00097
00098
00099
00100
00101
00102 static VALUE
00103 math_acos(obj, x)
00104 VALUE obj, x;
00105 {
00106 double d;
00107
00108 Need_Float(x);
00109 errno = 0;
00110 d = acos(RFLOAT(x)->value);
00111 if (errno) {
00112 rb_sys_fail("acos");
00113 }
00114 return rb_float_new(d);
00115 }
00116
00117
00118
00119
00120
00121
00122
00123
00124 static VALUE
00125 math_asin(obj, x)
00126 VALUE obj, x;
00127 {
00128 double d;
00129
00130 Need_Float(x);
00131 errno = 0;
00132 d = asin(RFLOAT(x)->value);
00133 if (errno) {
00134 rb_sys_fail("asin");
00135 }
00136 return rb_float_new(d);
00137 }
00138
00139
00140
00141
00142
00143
00144
00145
00146 static VALUE
00147 math_atan(obj, x)
00148 VALUE obj, x;
00149 {
00150 Need_Float(x);
00151 return rb_float_new(atan(RFLOAT(x)->value));
00152 }
00153
00154 #ifndef HAVE_COSH
00155 double
00156 cosh(x)
00157 double x;
00158 {
00159 return (exp(x) + exp(-x)) / 2;
00160 }
00161 #endif
00162
00163
00164
00165
00166
00167
00168
00169
00170 static VALUE
00171 math_cosh(obj, x)
00172 VALUE obj, x;
00173 {
00174 Need_Float(x);
00175
00176 return rb_float_new(cosh(RFLOAT(x)->value));
00177 }
00178
00179 #ifndef HAVE_SINH
00180 double
00181 sinh(x)
00182 double x;
00183 {
00184 return (exp(x) - exp(-x)) / 2;
00185 }
00186 #endif
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196 static VALUE
00197 math_sinh(obj, x)
00198 VALUE obj, x;
00199 {
00200 Need_Float(x);
00201 return rb_float_new(sinh(RFLOAT(x)->value));
00202 }
00203
00204 #ifndef HAVE_TANH
00205 double
00206 tanh(x)
00207 double x;
00208 {
00209 return sinh(x) / cosh(x);
00210 }
00211 #endif
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221 static VALUE
00222 math_tanh(obj, x)
00223 VALUE obj, x;
00224 {
00225 Need_Float(x);
00226 return rb_float_new(tanh(RFLOAT(x)->value));
00227 }
00228
00229
00230
00231
00232
00233
00234
00235
00236 static VALUE
00237 math_acosh(obj, x)
00238 VALUE obj, x;
00239 {
00240 double d;
00241
00242 Need_Float(x);
00243 errno = 0;
00244 d = acosh(RFLOAT(x)->value);
00245 if (errno) {
00246 rb_sys_fail("acosh");
00247 }
00248 return rb_float_new(d);
00249 }
00250
00251
00252
00253
00254
00255
00256
00257
00258 static VALUE
00259 math_asinh(obj, x)
00260 VALUE obj, x;
00261 {
00262 Need_Float(x);
00263 return rb_float_new(asinh(RFLOAT(x)->value));
00264 }
00265
00266
00267
00268
00269
00270
00271
00272
00273 static VALUE
00274 math_atanh(obj, x)
00275 VALUE obj, x;
00276 {
00277 double d;
00278
00279 Need_Float(x);
00280 errno = 0;
00281 d = atanh(RFLOAT(x)->value);
00282 if (errno) {
00283 rb_sys_fail("atanh");
00284 }
00285 return rb_float_new(d);
00286 }
00287
00288
00289
00290
00291
00292
00293
00294
00295 static VALUE
00296 math_exp(obj, x)
00297 VALUE obj, x;
00298 {
00299 Need_Float(x);
00300 return rb_float_new(exp(RFLOAT(x)->value));
00301 }
00302
00303 #if defined __CYGWIN__
00304 # include <cygwin/version.h>
00305 # if CYGWIN_VERSION_DLL_MAJOR < 1005
00306 # define nan(x) nan()
00307 # endif
00308 # define log(x) ((x) < 0.0 ? nan("") : log(x))
00309 # define log10(x) ((x) < 0.0 ? nan("") : log10(x))
00310 #endif
00311
00312
00313
00314
00315
00316
00317
00318
00319 static VALUE
00320 math_log(obj, x)
00321 VALUE obj, x;
00322 {
00323 double d;
00324
00325 Need_Float(x);
00326 errno = 0;
00327 d = log(RFLOAT(x)->value);
00328 if (errno) {
00329 rb_sys_fail("log");
00330 }
00331 return rb_float_new(d);
00332 }
00333
00334
00335
00336
00337
00338
00339
00340
00341 static VALUE
00342 math_log10(obj, x)
00343 VALUE obj, x;
00344 {
00345 double d;
00346
00347 Need_Float(x);
00348 errno = 0;
00349 d = log10(RFLOAT(x)->value);
00350 if (errno) {
00351 rb_sys_fail("log10");
00352 }
00353 return rb_float_new(d);
00354 }
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364 static VALUE
00365 math_sqrt(obj, x)
00366 VALUE obj, x;
00367 {
00368 double d;
00369
00370 Need_Float(x);
00371 errno = 0;
00372 d = sqrt(RFLOAT(x)->value);
00373 if (errno) {
00374 rb_sys_fail("sqrt");
00375 }
00376 return rb_float_new(d);
00377 }
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391 static VALUE
00392 math_frexp(obj, x)
00393 VALUE obj, x;
00394 {
00395 double d;
00396 int exp;
00397
00398 Need_Float(x);
00399
00400 d = frexp(RFLOAT(x)->value, &exp);
00401 return rb_assoc_new(rb_float_new(d), INT2NUM(exp));
00402 }
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414 static VALUE
00415 math_ldexp(obj, x, n)
00416 VALUE obj, x, n;
00417 {
00418 Need_Float(x);
00419 return rb_float_new(ldexp(RFLOAT(x)->value, NUM2INT(n)));
00420 }
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432 static VALUE
00433 math_hypot(obj, x, y)
00434 VALUE obj, x, y;
00435 {
00436 Need_Float2(x, y);
00437 return rb_float_new(hypot(RFLOAT(x)->value, RFLOAT(y)->value));
00438 }
00439
00440
00441
00442
00443
00444
00445
00446
00447 static VALUE
00448 math_erf(obj, x)
00449 VALUE obj, x;
00450 {
00451 Need_Float(x);
00452 return rb_float_new(erf(RFLOAT(x)->value));
00453 }
00454
00455
00456
00457
00458
00459
00460
00461
00462 static VALUE
00463 math_erfc(obj, x)
00464 VALUE obj, x;
00465 {
00466 Need_Float(x);
00467 return rb_float_new(erfc(RFLOAT(x)->value));
00468 }
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478 void
00479 Init_Math()
00480 {
00481 rb_mMath = rb_define_module("Math");
00482
00483 #ifdef M_PI
00484 rb_define_const(rb_mMath, "PI", rb_float_new(M_PI));
00485 #else
00486 rb_define_const(rb_mMath, "PI", rb_float_new(atan(1.0)*4.0));
00487 #endif
00488
00489 #ifdef M_E
00490 rb_define_const(rb_mMath, "E", rb_float_new(M_E));
00491 #else
00492 rb_define_const(rb_mMath, "E", rb_float_new(exp(1.0)));
00493 #endif
00494
00495 rb_define_module_function(rb_mMath, "atan2", math_atan2, 2);
00496 rb_define_module_function(rb_mMath, "cos", math_cos, 1);
00497 rb_define_module_function(rb_mMath, "sin", math_sin, 1);
00498 rb_define_module_function(rb_mMath, "tan", math_tan, 1);
00499
00500 rb_define_module_function(rb_mMath, "acos", math_acos, 1);
00501 rb_define_module_function(rb_mMath, "asin", math_asin, 1);
00502 rb_define_module_function(rb_mMath, "atan", math_atan, 1);
00503
00504 rb_define_module_function(rb_mMath, "cosh", math_cosh, 1);
00505 rb_define_module_function(rb_mMath, "sinh", math_sinh, 1);
00506 rb_define_module_function(rb_mMath, "tanh", math_tanh, 1);
00507
00508 rb_define_module_function(rb_mMath, "acosh", math_acosh, 1);
00509 rb_define_module_function(rb_mMath, "asinh", math_asinh, 1);
00510 rb_define_module_function(rb_mMath, "atanh", math_atanh, 1);
00511
00512 rb_define_module_function(rb_mMath, "exp", math_exp, 1);
00513 rb_define_module_function(rb_mMath, "log", math_log, 1);
00514 rb_define_module_function(rb_mMath, "log10", math_log10, 1);
00515 rb_define_module_function(rb_mMath, "sqrt", math_sqrt, 1);
00516
00517 rb_define_module_function(rb_mMath, "frexp", math_frexp, 1);
00518 rb_define_module_function(rb_mMath, "ldexp", math_ldexp, 2);
00519
00520 rb_define_module_function(rb_mMath, "hypot", math_hypot, 2);
00521
00522 rb_define_module_function(rb_mMath, "erf", math_erf, 1);
00523 rb_define_module_function(rb_mMath, "erfc", math_erfc, 1);
00524 }
00525