PageRenderTime 44ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 1ms

/math.c

https://github.com/diabolo/ruby
C | 813 lines | 377 code | 99 blank | 337 comment | 42 complexity | 68ea164d488d8cb999240714344461e9 MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause
  1. /**********************************************************************
  2. math.c -
  3. $Author$
  4. created at: Tue Jan 25 14:12:56 JST 1994
  5. Copyright (C) 1993-2007 Yukihiro Matsumoto
  6. **********************************************************************/
  7. #include "ruby/ruby.h"
  8. #include <math.h>
  9. #include <errno.h>
  10. #define numberof(array) (int)(sizeof(array) / sizeof((array)[0]))
  11. VALUE rb_mMath;
  12. VALUE rb_eMathDomainError;
  13. extern VALUE rb_to_float(VALUE val);
  14. #define Need_Float(x) do {if (TYPE(x) != T_FLOAT) {(x) = rb_to_float(x);}} while(0)
  15. #define Need_Float2(x,y) do {\
  16. Need_Float(x);\
  17. Need_Float(y);\
  18. } while (0)
  19. #define domain_error(msg) \
  20. rb_raise(rb_eMathDomainError, "Numerical argument is out of domain - " #msg);
  21. /*
  22. * call-seq:
  23. * Math.atan2(y, x) -> float
  24. *
  25. * Computes the arc tangent given <i>y</i> and <i>x</i>. Returns
  26. * -PI..PI.
  27. *
  28. * Math.atan2(-0.0, -1.0) #=> -3.141592653589793
  29. * Math.atan2(-1.0, -1.0) #=> -2.356194490192345
  30. * Math.atan2(-1.0, 0.0) #=> -1.5707963267948966
  31. * Math.atan2(-1.0, 1.0) #=> -0.7853981633974483
  32. * Math.atan2(-0.0, 1.0) #=> -0.0
  33. * Math.atan2(0.0, 1.0) #=> 0.0
  34. * Math.atan2(1.0, 1.0) #=> 0.7853981633974483
  35. * Math.atan2(1.0, 0.0) #=> 1.5707963267948966
  36. * Math.atan2(1.0, -1.0) #=> 2.356194490192345
  37. * Math.atan2(0.0, -1.0) #=> 3.141592653589793
  38. *
  39. */
  40. static VALUE
  41. math_atan2(VALUE obj, VALUE y, VALUE x)
  42. {
  43. double dx, dy;
  44. Need_Float2(y, x);
  45. dx = RFLOAT_VALUE(x);
  46. dy = RFLOAT_VALUE(y);
  47. if (dx == 0.0 && dy == 0.0) domain_error("atan2");
  48. if (isinf(dx) && isinf(dy)) domain_error("atan2");
  49. return DBL2NUM(atan2(dy, dx));
  50. }
  51. /*
  52. * call-seq:
  53. * Math.cos(x) -> float
  54. *
  55. * Computes the cosine of <i>x</i> (expressed in radians). Returns
  56. * -1..1.
  57. */
  58. static VALUE
  59. math_cos(VALUE obj, VALUE x)
  60. {
  61. Need_Float(x);
  62. return DBL2NUM(cos(RFLOAT_VALUE(x)));
  63. }
  64. /*
  65. * call-seq:
  66. * Math.sin(x) -> float
  67. *
  68. * Computes the sine of <i>x</i> (expressed in radians). Returns
  69. * -1..1.
  70. */
  71. static VALUE
  72. math_sin(VALUE obj, VALUE x)
  73. {
  74. Need_Float(x);
  75. return DBL2NUM(sin(RFLOAT_VALUE(x)));
  76. }
  77. /*
  78. * call-seq:
  79. * Math.tan(x) -> float
  80. *
  81. * Returns the tangent of <i>x</i> (expressed in radians).
  82. */
  83. static VALUE
  84. math_tan(VALUE obj, VALUE x)
  85. {
  86. Need_Float(x);
  87. return DBL2NUM(tan(RFLOAT_VALUE(x)));
  88. }
  89. /*
  90. * call-seq:
  91. * Math.acos(x) -> float
  92. *
  93. * Computes the arc cosine of <i>x</i>. Returns 0..PI.
  94. */
  95. static VALUE
  96. math_acos(VALUE obj, VALUE x)
  97. {
  98. double d0, d;
  99. Need_Float(x);
  100. d0 = RFLOAT_VALUE(x);
  101. /* check for domain error */
  102. if (d0 < -1.0 || 1.0 < d0) domain_error("acos");
  103. d = acos(d0);
  104. return DBL2NUM(d);
  105. }
  106. /*
  107. * call-seq:
  108. * Math.asin(x) -> float
  109. *
  110. * Computes the arc sine of <i>x</i>. Returns -{PI/2} .. {PI/2}.
  111. */
  112. static VALUE
  113. math_asin(VALUE obj, VALUE x)
  114. {
  115. double d0, d;
  116. Need_Float(x);
  117. d0 = RFLOAT_VALUE(x);
  118. /* check for domain error */
  119. if (d0 < -1.0 || 1.0 < d0) domain_error("asin");
  120. d = asin(d0);
  121. return DBL2NUM(d);
  122. }
  123. /*
  124. * call-seq:
  125. * Math.atan(x) -> float
  126. *
  127. * Computes the arc tangent of <i>x</i>. Returns -{PI/2} .. {PI/2}.
  128. */
  129. static VALUE
  130. math_atan(VALUE obj, VALUE x)
  131. {
  132. Need_Float(x);
  133. return DBL2NUM(atan(RFLOAT_VALUE(x)));
  134. }
  135. #ifndef HAVE_COSH
  136. double
  137. cosh(double x)
  138. {
  139. return (exp(x) + exp(-x)) / 2;
  140. }
  141. #endif
  142. /*
  143. * call-seq:
  144. * Math.cosh(x) -> float
  145. *
  146. * Computes the hyperbolic cosine of <i>x</i> (expressed in radians).
  147. */
  148. static VALUE
  149. math_cosh(VALUE obj, VALUE x)
  150. {
  151. Need_Float(x);
  152. return DBL2NUM(cosh(RFLOAT_VALUE(x)));
  153. }
  154. #ifndef HAVE_SINH
  155. double
  156. sinh(double x)
  157. {
  158. return (exp(x) - exp(-x)) / 2;
  159. }
  160. #endif
  161. /*
  162. * call-seq:
  163. * Math.sinh(x) -> float
  164. *
  165. * Computes the hyperbolic sine of <i>x</i> (expressed in
  166. * radians).
  167. */
  168. static VALUE
  169. math_sinh(VALUE obj, VALUE x)
  170. {
  171. Need_Float(x);
  172. return DBL2NUM(sinh(RFLOAT_VALUE(x)));
  173. }
  174. #ifndef HAVE_TANH
  175. double
  176. tanh(double x)
  177. {
  178. return sinh(x) / cosh(x);
  179. }
  180. #endif
  181. /*
  182. * call-seq:
  183. * Math.tanh() -> float
  184. *
  185. * Computes the hyperbolic tangent of <i>x</i> (expressed in
  186. * radians).
  187. */
  188. static VALUE
  189. math_tanh(VALUE obj, VALUE x)
  190. {
  191. Need_Float(x);
  192. return DBL2NUM(tanh(RFLOAT_VALUE(x)));
  193. }
  194. /*
  195. * call-seq:
  196. * Math.acosh(x) -> float
  197. *
  198. * Computes the inverse hyperbolic cosine of <i>x</i>.
  199. */
  200. static VALUE
  201. math_acosh(VALUE obj, VALUE x)
  202. {
  203. double d0, d;
  204. Need_Float(x);
  205. d0 = RFLOAT_VALUE(x);
  206. /* check for domain error */
  207. if (d0 < 1.0) domain_error("acosh");
  208. d = acosh(d0);
  209. return DBL2NUM(d);
  210. }
  211. /*
  212. * call-seq:
  213. * Math.asinh(x) -> float
  214. *
  215. * Computes the inverse hyperbolic sine of <i>x</i>.
  216. */
  217. static VALUE
  218. math_asinh(VALUE obj, VALUE x)
  219. {
  220. Need_Float(x);
  221. return DBL2NUM(asinh(RFLOAT_VALUE(x)));
  222. }
  223. /*
  224. * call-seq:
  225. * Math.atanh(x) -> float
  226. *
  227. * Computes the inverse hyperbolic tangent of <i>x</i>.
  228. */
  229. static VALUE
  230. math_atanh(VALUE obj, VALUE x)
  231. {
  232. double d0, d;
  233. Need_Float(x);
  234. d0 = RFLOAT_VALUE(x);
  235. /* check for domain error */
  236. if (d0 < -1.0 || +1.0 < d0) domain_error("atanh");
  237. /* check for pole error */
  238. if (d0 == -1.0) return DBL2NUM(-INFINITY);
  239. if (d0 == +1.0) return DBL2NUM(+INFINITY);
  240. d = atanh(d0);
  241. return DBL2NUM(d);
  242. }
  243. /*
  244. * call-seq:
  245. * Math.exp(x) -> float
  246. *
  247. * Returns e**x.
  248. *
  249. * Math.exp(0) #=> 1.0
  250. * Math.exp(1) #=> 2.718281828459045
  251. * Math.exp(1.5) #=> 4.4816890703380645
  252. *
  253. */
  254. static VALUE
  255. math_exp(VALUE obj, VALUE x)
  256. {
  257. Need_Float(x);
  258. return DBL2NUM(exp(RFLOAT_VALUE(x)));
  259. }
  260. #if defined __CYGWIN__
  261. # include <cygwin/version.h>
  262. # if CYGWIN_VERSION_DLL_MAJOR < 1005
  263. # define nan(x) nan()
  264. # endif
  265. # define log(x) ((x) < 0.0 ? nan("") : log(x))
  266. # define log10(x) ((x) < 0.0 ? nan("") : log10(x))
  267. #endif
  268. /*
  269. * call-seq:
  270. * Math.log(numeric) -> float
  271. * Math.log(num,base) -> float
  272. *
  273. * Returns the natural logarithm of <i>numeric</i>.
  274. * If additional second argument is given, it will be the base
  275. * of logarithm.
  276. *
  277. * Math.log(1) #=> 0.0
  278. * Math.log(Math::E) #=> 1.0
  279. * Math.log(Math::E**3) #=> 3.0
  280. * Math.log(12,3) #=> 2.2618595071429146
  281. *
  282. */
  283. static VALUE
  284. math_log(int argc, VALUE *argv)
  285. {
  286. VALUE x, base;
  287. double d0, d;
  288. rb_scan_args(argc, argv, "11", &x, &base);
  289. Need_Float(x);
  290. d0 = RFLOAT_VALUE(x);
  291. /* check for domain error */
  292. if (d0 < 0.0) domain_error("log");
  293. /* check for pole error */
  294. if (d0 == 0.0) return DBL2NUM(-INFINITY);
  295. d = log(d0);
  296. if (argc == 2) {
  297. Need_Float(base);
  298. d /= log(RFLOAT_VALUE(base));
  299. }
  300. return DBL2NUM(d);
  301. }
  302. #ifndef log2
  303. #ifndef HAVE_LOG2
  304. double
  305. log2(double x)
  306. {
  307. return log10(x)/log10(2.0);
  308. }
  309. #else
  310. extern double log2(double);
  311. #endif
  312. #endif
  313. /*
  314. * call-seq:
  315. * Math.log2(numeric) -> float
  316. *
  317. * Returns the base 2 logarithm of <i>numeric</i>.
  318. *
  319. * Math.log2(1) #=> 0.0
  320. * Math.log2(2) #=> 1.0
  321. * Math.log2(32768) #=> 15.0
  322. * Math.log2(65536) #=> 16.0
  323. *
  324. */
  325. static VALUE
  326. math_log2(VALUE obj, VALUE x)
  327. {
  328. double d0, d;
  329. Need_Float(x);
  330. d0 = RFLOAT_VALUE(x);
  331. /* check for domain error */
  332. if (d0 < 0.0) domain_error("log2");
  333. /* check for pole error */
  334. if (d0 == 0.0) return DBL2NUM(-INFINITY);
  335. d = log2(d0);
  336. return DBL2NUM(d);
  337. }
  338. /*
  339. * call-seq:
  340. * Math.log10(numeric) -> float
  341. *
  342. * Returns the base 10 logarithm of <i>numeric</i>.
  343. *
  344. * Math.log10(1) #=> 0.0
  345. * Math.log10(10) #=> 1.0
  346. * Math.log10(10**100) #=> 100.0
  347. *
  348. */
  349. static VALUE
  350. math_log10(VALUE obj, VALUE x)
  351. {
  352. double d0, d;
  353. Need_Float(x);
  354. d0 = RFLOAT_VALUE(x);
  355. /* check for domain error */
  356. if (d0 < 0.0) domain_error("log10");
  357. /* check for pole error */
  358. if (d0 == 0.0) return DBL2NUM(-INFINITY);
  359. d = log10(d0);
  360. return DBL2NUM(d);
  361. }
  362. /*
  363. * call-seq:
  364. * Math.sqrt(numeric) -> float
  365. *
  366. * Returns the non-negative square root of <i>numeric</i>.
  367. *
  368. * 0.upto(10) {|x|
  369. * p [x, Math.sqrt(x), Math.sqrt(x)**2]
  370. * }
  371. * #=>
  372. * [0, 0.0, 0.0]
  373. * [1, 1.0, 1.0]
  374. * [2, 1.4142135623731, 2.0]
  375. * [3, 1.73205080756888, 3.0]
  376. * [4, 2.0, 4.0]
  377. * [5, 2.23606797749979, 5.0]
  378. * [6, 2.44948974278318, 6.0]
  379. * [7, 2.64575131106459, 7.0]
  380. * [8, 2.82842712474619, 8.0]
  381. * [9, 3.0, 9.0]
  382. * [10, 3.16227766016838, 10.0]
  383. *
  384. */
  385. static VALUE
  386. math_sqrt(VALUE obj, VALUE x)
  387. {
  388. double d0, d;
  389. Need_Float(x);
  390. d0 = RFLOAT_VALUE(x);
  391. /* check for domain error */
  392. if (d0 < 0.0) domain_error("sqrt");
  393. if (d0 == 0.0) return DBL2NUM(0.0);
  394. d = sqrt(d0);
  395. return DBL2NUM(d);
  396. }
  397. /*
  398. * call-seq:
  399. * Math.cbrt(numeric) -> float
  400. *
  401. * Returns the cube root of <i>numeric</i>.
  402. *
  403. * -9.upto(9) {|x|
  404. * p [x, Math.cbrt(x), Math.cbrt(x)**3]
  405. * }
  406. * #=>
  407. * [-9, -2.0800838230519, -9.0]
  408. * [-8, -2.0, -8.0]
  409. * [-7, -1.91293118277239, -7.0]
  410. * [-6, -1.81712059283214, -6.0]
  411. * [-5, -1.7099759466767, -5.0]
  412. * [-4, -1.5874010519682, -4.0]
  413. * [-3, -1.44224957030741, -3.0]
  414. * [-2, -1.25992104989487, -2.0]
  415. * [-1, -1.0, -1.0]
  416. * [0, 0.0, 0.0]
  417. * [1, 1.0, 1.0]
  418. * [2, 1.25992104989487, 2.0]
  419. * [3, 1.44224957030741, 3.0]
  420. * [4, 1.5874010519682, 4.0]
  421. * [5, 1.7099759466767, 5.0]
  422. * [6, 1.81712059283214, 6.0]
  423. * [7, 1.91293118277239, 7.0]
  424. * [8, 2.0, 8.0]
  425. * [9, 2.0800838230519, 9.0]
  426. *
  427. */
  428. static VALUE
  429. math_cbrt(VALUE obj, VALUE x)
  430. {
  431. Need_Float(x);
  432. return DBL2NUM(cbrt(RFLOAT_VALUE(x)));
  433. }
  434. /*
  435. * call-seq:
  436. * Math.frexp(numeric) -> [ fraction, exponent ]
  437. *
  438. * Returns a two-element array containing the normalized fraction (a
  439. * <code>Float</code>) and exponent (a <code>Fixnum</code>) of
  440. * <i>numeric</i>.
  441. *
  442. * fraction, exponent = Math.frexp(1234) #=> [0.6025390625, 11]
  443. * fraction * 2**exponent #=> 1234.0
  444. */
  445. static VALUE
  446. math_frexp(VALUE obj, VALUE x)
  447. {
  448. double d;
  449. int exp;
  450. Need_Float(x);
  451. d = frexp(RFLOAT_VALUE(x), &exp);
  452. return rb_assoc_new(DBL2NUM(d), INT2NUM(exp));
  453. }
  454. /*
  455. * call-seq:
  456. * Math.ldexp(flt, int) -> float
  457. *
  458. * Returns the value of <i>flt</i>*(2**<i>int</i>).
  459. *
  460. * fraction, exponent = Math.frexp(1234)
  461. * Math.ldexp(fraction, exponent) #=> 1234.0
  462. */
  463. static VALUE
  464. math_ldexp(VALUE obj, VALUE x, VALUE n)
  465. {
  466. Need_Float(x);
  467. return DBL2NUM(ldexp(RFLOAT_VALUE(x), NUM2INT(n)));
  468. }
  469. /*
  470. * call-seq:
  471. * Math.hypot(x, y) -> float
  472. *
  473. * Returns sqrt(x**2 + y**2), the hypotenuse of a right-angled triangle
  474. * with sides <i>x</i> and <i>y</i>.
  475. *
  476. * Math.hypot(3, 4) #=> 5.0
  477. */
  478. static VALUE
  479. math_hypot(VALUE obj, VALUE x, VALUE y)
  480. {
  481. Need_Float2(x, y);
  482. return DBL2NUM(hypot(RFLOAT_VALUE(x), RFLOAT_VALUE(y)));
  483. }
  484. /*
  485. * call-seq:
  486. * Math.erf(x) -> float
  487. *
  488. * Calculates the error function of x.
  489. */
  490. static VALUE
  491. math_erf(VALUE obj, VALUE x)
  492. {
  493. Need_Float(x);
  494. return DBL2NUM(erf(RFLOAT_VALUE(x)));
  495. }
  496. /*
  497. * call-seq:
  498. * Math.erfc(x) -> float
  499. *
  500. * Calculates the complementary error function of x.
  501. */
  502. static VALUE
  503. math_erfc(VALUE obj, VALUE x)
  504. {
  505. Need_Float(x);
  506. return DBL2NUM(erfc(RFLOAT_VALUE(x)));
  507. }
  508. /*
  509. * call-seq:
  510. * Math.gamma(x) -> float
  511. *
  512. * Calculates the gamma function of x.
  513. *
  514. * Note that gamma(n) is same as fact(n-1) for integer n > 0.
  515. * However gamma(n) returns float and can be an approximation.
  516. *
  517. * def fact(n) (1..n).inject(1) {|r,i| r*i } end
  518. * 1.upto(26) {|i| p [i, Math.gamma(i), fact(i-1)] }
  519. * #=> [1, 1.0, 1]
  520. * # [2, 1.0, 1]
  521. * # [3, 2.0, 2]
  522. * # [4, 6.0, 6]
  523. * # [5, 24.0, 24]
  524. * # [6, 120.0, 120]
  525. * # [7, 720.0, 720]
  526. * # [8, 5040.0, 5040]
  527. * # [9, 40320.0, 40320]
  528. * # [10, 362880.0, 362880]
  529. * # [11, 3628800.0, 3628800]
  530. * # [12, 39916800.0, 39916800]
  531. * # [13, 479001600.0, 479001600]
  532. * # [14, 6227020800.0, 6227020800]
  533. * # [15, 87178291200.0, 87178291200]
  534. * # [16, 1307674368000.0, 1307674368000]
  535. * # [17, 20922789888000.0, 20922789888000]
  536. * # [18, 355687428096000.0, 355687428096000]
  537. * # [19, 6.402373705728e+15, 6402373705728000]
  538. * # [20, 1.21645100408832e+17, 121645100408832000]
  539. * # [21, 2.43290200817664e+18, 2432902008176640000]
  540. * # [22, 5.109094217170944e+19, 51090942171709440000]
  541. * # [23, 1.1240007277776077e+21, 1124000727777607680000]
  542. * # [24, 2.5852016738885062e+22, 25852016738884976640000]
  543. * # [25, 6.204484017332391e+23, 620448401733239439360000]
  544. * # [26, 1.5511210043330954e+25, 15511210043330985984000000]
  545. *
  546. */
  547. static VALUE
  548. math_gamma(VALUE obj, VALUE x)
  549. {
  550. static const double fact_table[] = {
  551. /* fact(0) */ 1.0,
  552. /* fact(1) */ 1.0,
  553. /* fact(2) */ 2.0,
  554. /* fact(3) */ 6.0,
  555. /* fact(4) */ 24.0,
  556. /* fact(5) */ 120.0,
  557. /* fact(6) */ 720.0,
  558. /* fact(7) */ 5040.0,
  559. /* fact(8) */ 40320.0,
  560. /* fact(9) */ 362880.0,
  561. /* fact(10) */ 3628800.0,
  562. /* fact(11) */ 39916800.0,
  563. /* fact(12) */ 479001600.0,
  564. /* fact(13) */ 6227020800.0,
  565. /* fact(14) */ 87178291200.0,
  566. /* fact(15) */ 1307674368000.0,
  567. /* fact(16) */ 20922789888000.0,
  568. /* fact(17) */ 355687428096000.0,
  569. /* fact(18) */ 6402373705728000.0,
  570. /* fact(19) */ 121645100408832000.0,
  571. /* fact(20) */ 2432902008176640000.0,
  572. /* fact(21) */ 51090942171709440000.0,
  573. /* fact(22) */ 1124000727777607680000.0,
  574. /* fact(23)=25852016738884976640000 needs 56bit mantissa which is
  575. * impossible to represent exactly in IEEE 754 double which have
  576. * 53bit mantissa. */
  577. };
  578. double d0, d;
  579. double intpart, fracpart;
  580. Need_Float(x);
  581. d0 = RFLOAT_VALUE(x);
  582. /* check for domain error */
  583. if (isinf(d0) && signbit(d0)) domain_error("gamma");
  584. fracpart = modf(d0, &intpart);
  585. if (fracpart == 0.0) {
  586. if (intpart < 0) domain_error("gamma");
  587. if (0 < intpart &&
  588. intpart - 1 < (double)numberof(fact_table)) {
  589. return DBL2NUM(fact_table[(int)intpart - 1]);
  590. }
  591. }
  592. d = tgamma(d0);
  593. return DBL2NUM(d);
  594. }
  595. /*
  596. * call-seq:
  597. * Math.lgamma(x) -> [float, -1 or 1]
  598. *
  599. * Calculates the logarithmic gamma of x and
  600. * the sign of gamma of x.
  601. *
  602. * Math.lgamma(x) is same as
  603. * [Math.log(Math.gamma(x).abs), Math.gamma(x) < 0 ? -1 : 1]
  604. * but avoid overflow by Math.gamma(x) for large x.
  605. */
  606. static VALUE
  607. math_lgamma(VALUE obj, VALUE x)
  608. {
  609. double d0, d;
  610. int sign=1;
  611. VALUE v;
  612. Need_Float(x);
  613. d0 = RFLOAT_VALUE(x);
  614. /* check for domain error */
  615. if (isinf(d0)) {
  616. if (signbit(d0)) domain_error("lgamma");
  617. return rb_assoc_new(DBL2NUM(INFINITY), INT2FIX(1));
  618. }
  619. d = lgamma_r(d0, &sign);
  620. v = DBL2NUM(d);
  621. return rb_assoc_new(v, INT2FIX(sign));
  622. }
  623. #define exp1(n) \
  624. VALUE \
  625. rb_math_##n(VALUE x)\
  626. {\
  627. return math_##n(rb_mMath, x);\
  628. }
  629. #define exp2(n) \
  630. VALUE \
  631. rb_math_##n(VALUE x, VALUE y)\
  632. {\
  633. return math_##n(rb_mMath, x, y);\
  634. }
  635. exp2(atan2)
  636. exp1(cos)
  637. exp1(cosh)
  638. exp1(exp)
  639. exp2(hypot)
  640. VALUE
  641. rb_math_log(int argc, VALUE *argv)
  642. {
  643. return math_log(argc, argv);
  644. }
  645. exp1(sin)
  646. exp1(sinh)
  647. exp1(sqrt)
  648. /*
  649. * Document-class: Math::DomainError
  650. *
  651. * Raised when a mathematical function is evaluated outside of its
  652. * domain of definition.
  653. *
  654. * For example, since +cos+ returns values in the range -1..1,
  655. * its inverse function +acos+ is only defined on that interval:
  656. *
  657. * Math.acos(42)
  658. *
  659. * <em>produces:</em>
  660. *
  661. * Math::DomainError: Numerical argument is out of domain - "acos"
  662. */
  663. /*
  664. * The <code>Math</code> module contains module functions for basic
  665. * trigonometric and transcendental functions. See class
  666. * <code>Float</code> for a list of constants that
  667. * define Ruby's floating point accuracy.
  668. */
  669. void
  670. Init_Math(void)
  671. {
  672. rb_mMath = rb_define_module("Math");
  673. rb_eMathDomainError = rb_define_class_under(rb_mMath, "DomainError", rb_eStandardError);
  674. #ifdef M_PI
  675. rb_define_const(rb_mMath, "PI", DBL2NUM(M_PI));
  676. #else
  677. rb_define_const(rb_mMath, "PI", DBL2NUM(atan(1.0)*4.0));
  678. #endif
  679. #ifdef M_E
  680. rb_define_const(rb_mMath, "E", DBL2NUM(M_E));
  681. #else
  682. rb_define_const(rb_mMath, "E", DBL2NUM(exp(1.0)));
  683. #endif
  684. rb_define_module_function(rb_mMath, "atan2", math_atan2, 2);
  685. rb_define_module_function(rb_mMath, "cos", math_cos, 1);
  686. rb_define_module_function(rb_mMath, "sin", math_sin, 1);
  687. rb_define_module_function(rb_mMath, "tan", math_tan, 1);
  688. rb_define_module_function(rb_mMath, "acos", math_acos, 1);
  689. rb_define_module_function(rb_mMath, "asin", math_asin, 1);
  690. rb_define_module_function(rb_mMath, "atan", math_atan, 1);
  691. rb_define_module_function(rb_mMath, "cosh", math_cosh, 1);
  692. rb_define_module_function(rb_mMath, "sinh", math_sinh, 1);
  693. rb_define_module_function(rb_mMath, "tanh", math_tanh, 1);
  694. rb_define_module_function(rb_mMath, "acosh", math_acosh, 1);
  695. rb_define_module_function(rb_mMath, "asinh", math_asinh, 1);
  696. rb_define_module_function(rb_mMath, "atanh", math_atanh, 1);
  697. rb_define_module_function(rb_mMath, "exp", math_exp, 1);
  698. rb_define_module_function(rb_mMath, "log", math_log, -1);
  699. rb_define_module_function(rb_mMath, "log2", math_log2, 1);
  700. rb_define_module_function(rb_mMath, "log10", math_log10, 1);
  701. rb_define_module_function(rb_mMath, "sqrt", math_sqrt, 1);
  702. rb_define_module_function(rb_mMath, "cbrt", math_cbrt, 1);
  703. rb_define_module_function(rb_mMath, "frexp", math_frexp, 1);
  704. rb_define_module_function(rb_mMath, "ldexp", math_ldexp, 2);
  705. rb_define_module_function(rb_mMath, "hypot", math_hypot, 2);
  706. rb_define_module_function(rb_mMath, "erf", math_erf, 1);
  707. rb_define_module_function(rb_mMath, "erfc", math_erfc, 1);
  708. rb_define_module_function(rb_mMath, "gamma", math_gamma, 1);
  709. rb_define_module_function(rb_mMath, "lgamma", math_lgamma, 1);
  710. }