math.c


DEFINITIONS

This source file includes following functions.
  1. math_atan2
  2. math_cos
  3. math_sin
  4. math_tan
  5. math_acos
  6. math_asin
  7. math_atan
  8. cosh
  9. math_cosh
  10. sinh
  11. math_sinh
  12. tanh
  13. math_tanh
  14. math_acosh
  15. math_asinh
  16. math_atanh
  17. math_exp
  18. math_log
  19. math_log10
  20. math_sqrt
  21. math_frexp
  22. math_ldexp
  23. math_hypot
  24. Init_Math


   1  /**********************************************************************
   2  
   3    math.c -
   4  
   5    $Author: matz $
   6    $Date: 2002/04/18 08:46:18 $
   7    created at: Tue Jan 25 14:12:56 JST 1994
   8  
   9    Copyright (C) 1993-2002 Yukihiro Matsumoto
  10  
  11  **********************************************************************/
  12  
  13  #include "ruby.h"
  14  #include <math.h>
  15  
  16  VALUE rb_mMath;
  17  
  18  #define Need_Float(x) (x) = rb_Float(x)
  19  #define Need_Float2(x,y) do {\
  20      Need_Float(x);\
  21      Need_Float(y);\
  22  } while (0)
  23  
  24  static VALUE
  25  math_atan2(obj, y, x)
  26      VALUE obj, x, y;
  27  {
  28      Need_Float2(y, x);
  29      
  30      return rb_float_new(atan2(RFLOAT(y)->value, RFLOAT(x)->value));
  31  }
  32  
  33  static VALUE
  34  math_cos(obj, x)
  35      VALUE obj, x;
  36  {
  37      Need_Float(x);
  38  
  39      return rb_float_new(cos(RFLOAT(x)->value));
  40  }
  41  
  42  static VALUE
  43  math_sin(obj, x)
  44      VALUE obj, x;
  45  {
  46      Need_Float(x);
  47  
  48      return rb_float_new(sin(RFLOAT(x)->value));
  49  }
  50  
  51  static VALUE
  52  math_tan(obj, x)
  53      VALUE obj, x;
  54  {
  55      Need_Float(x);
  56  
  57      return rb_float_new(tan(RFLOAT(x)->value));
  58  }
  59  
  60  static VALUE
  61  math_acos(obj, x)
  62      VALUE obj, x;
  63  {
  64      Need_Float(x);
  65      /*
  66      if (RFLOAT(x)->value < -1.0 || RFLOAT(x)->value > 1.0)
  67          rb_raise(rb_eArgError, "Out of range (-1..1)");
  68      */
  69      return rb_float_new(acos(RFLOAT(x)->value));
  70  }
  71  
  72  static VALUE
  73  math_asin(obj, x)
  74      VALUE obj, x;
  75  {
  76      Need_Float(x);
  77      /*
  78      if (RFLOAT(x)->value < -1.0 || RFLOAT(x)->value > 1.0)
  79          rb_raise(rb_eArgError, "Out of range (-1..1)");
  80      */
  81      return rb_float_new(asin(RFLOAT(x)->value));
  82  }
  83  
  84  static VALUE
  85  math_atan(obj, x)
  86      VALUE obj, x;
  87  {
  88      Need_Float(x);
  89      
  90      return rb_float_new(atan(RFLOAT(x)->value));
  91  }
  92  
  93  #ifndef HAVE_COSH
  94  double
  95  cosh(x)
  96      double x;
  97  {
  98      return (exp(x) + exp(-x)) / 2;
  99  }
 100  #endif
 101  
 102  static VALUE
 103  math_cosh(obj, x)
 104      VALUE obj, x;
 105  {
 106      Need_Float(x);
 107      
 108      return rb_float_new(cosh(RFLOAT(x)->value));
 109  }
 110  
 111  #ifndef HAVE_SINH
 112  double
 113  sinh(x)
 114      double x;
 115  {
 116      return (exp(x) - exp(-x)) / 2;
 117  }
 118  #endif
 119  
 120  static VALUE
 121  math_sinh(obj, x)
 122      VALUE obj, x;
 123  {
 124      Need_Float(x);
 125      
 126      return rb_float_new(sinh(RFLOAT(x)->value));
 127  }
 128  
 129  #ifndef HAVE_TANH
 130  double
 131  tanh(x)
 132      double x;
 133  {
 134      return sinh(x) / cosh(x);
 135  }
 136  #endif
 137  
 138  static VALUE
 139  math_tanh(obj, x)
 140      VALUE obj, x;
 141  {
 142      Need_Float(x);
 143      
 144      return rb_float_new(tanh(RFLOAT(x)->value));
 145  }
 146  
 147  static VALUE
 148  math_acosh(obj, x)
 149      VALUE obj, x;
 150  {
 151      Need_Float(x);
 152      
 153      return rb_float_new(acosh(RFLOAT(x)->value));
 154  }
 155  
 156  static VALUE
 157  math_asinh(obj, x)
 158      VALUE obj, x;
 159  {
 160      Need_Float(x);
 161      
 162      return rb_float_new(asinh(RFLOAT(x)->value));
 163  }
 164  
 165  static VALUE
 166  math_atanh(obj, x)
 167      VALUE obj, x;
 168  {
 169      Need_Float(x);
 170      
 171      return rb_float_new(atanh(RFLOAT(x)->value));
 172  }
 173  
 174  static VALUE
 175  math_exp(obj, x)
 176      VALUE obj, x;
 177  {
 178      Need_Float(x);
 179      
 180      return rb_float_new(exp(RFLOAT(x)->value));
 181  }
 182  
 183  #if defined __CYGWIN__
 184  #define log(x) ((x) < 0.0 ? nan() : log(x))
 185  #define log10(x) ((x) < 0.0 ? nan() : log10(x))
 186  #endif
 187  
 188  static VALUE
 189  math_log(obj, x)
 190      VALUE obj, x;
 191  {
 192      Need_Float(x);
 193      
 194      return rb_float_new(log(RFLOAT(x)->value));
 195  }
 196  
 197  static VALUE
 198  math_log10(obj, x)
 199      VALUE obj, x;
 200  {
 201      Need_Float(x);
 202      
 203      return rb_float_new(log10(RFLOAT(x)->value));
 204  }
 205  
 206  static VALUE
 207  math_sqrt(obj, x)
 208      VALUE obj, x;
 209  {
 210      Need_Float(x);
 211  
 212      if (RFLOAT(x)->value < 0.0) rb_raise(rb_eArgError, "square root for negative number");
 213      return rb_float_new(sqrt(RFLOAT(x)->value));
 214  }
 215  
 216  static VALUE
 217  math_frexp(obj, x)
 218      VALUE obj, x;
 219  {
 220      double d;
 221      int exp;
 222  
 223      Need_Float(x);
 224      
 225      d = frexp(RFLOAT(x)->value, &exp);
 226      return rb_assoc_new(rb_float_new(d), INT2NUM(exp));
 227  }
 228  
 229  static VALUE
 230  math_ldexp(obj, x, n)
 231      VALUE obj, x, n;
 232  {
 233      double d;
 234  
 235      Need_Float(x);
 236      
 237      return rb_float_new(d = ldexp(RFLOAT(x)->value, NUM2INT(n)));
 238  }
 239  
 240  static VALUE
 241  math_hypot(obj, x, y)
 242      VALUE obj, x, y;
 243  {
 244      Need_Float2(x, y);
 245      
 246      return rb_float_new(hypot(RFLOAT(x)->value, RFLOAT(y)->value));
 247  }
 248  
 249  void
 250  Init_Math()
 251  {
 252      rb_mMath = rb_define_module("Math");
 253  
 254  #ifdef M_PI
 255      rb_define_const(rb_mMath, "PI", rb_float_new(M_PI));
 256  #else
 257      rb_define_const(rb_mMath, "PI", rb_float_new(atan(1.0)*4.0));
 258  #endif
 259  
 260  #ifdef M_E
 261      rb_define_const(rb_mMath, "E", rb_float_new(M_E));
 262  #else
 263      rb_define_const(rb_mMath, "E", rb_float_new(exp(1.0)));
 264  #endif
 265  
 266      rb_define_module_function(rb_mMath, "atan2", math_atan2, 2);
 267      rb_define_module_function(rb_mMath, "cos", math_cos, 1);
 268      rb_define_module_function(rb_mMath, "sin", math_sin, 1);
 269      rb_define_module_function(rb_mMath, "tan", math_tan, 1);
 270  
 271      rb_define_module_function(rb_mMath, "acos", math_acos, 1);
 272      rb_define_module_function(rb_mMath, "asin", math_asin, 1);
 273      rb_define_module_function(rb_mMath, "atan", math_atan, 1);
 274  
 275      rb_define_module_function(rb_mMath, "cosh", math_cosh, 1);
 276      rb_define_module_function(rb_mMath, "sinh", math_sinh, 1);
 277      rb_define_module_function(rb_mMath, "tanh", math_tanh, 1);
 278  
 279      rb_define_module_function(rb_mMath, "acosh", math_acosh, 1);
 280      rb_define_module_function(rb_mMath, "asinh", math_asinh, 1);
 281      rb_define_module_function(rb_mMath, "atanh", math_atanh, 1);
 282  
 283      rb_define_module_function(rb_mMath, "exp", math_exp, 1);
 284      rb_define_module_function(rb_mMath, "log", math_log, 1);
 285      rb_define_module_function(rb_mMath, "log10", math_log10, 1);
 286      rb_define_module_function(rb_mMath, "sqrt", math_sqrt, 1);
 287  
 288      rb_define_module_function(rb_mMath, "frexp", math_frexp, 1);
 289      rb_define_module_function(rb_mMath, "ldexp", math_ldexp, 2);
 290  
 291      rb_define_module_function(rb_mMath, "hypot", math_hypot, 2);
 292  }