kjs Library: math_object.cpp Source File (kjs Library)

| # kjs Library API Documentation
Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Namespaces | Source Files

# math_object.cpp

    00001 // -*- c-basic-offset: 2 -*-
    00002 /*
    00003  *  This file is part of the KDE libraries
    00004  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
    00005  *
    00006  *  This library is free software; you can redistribute it and/or
    00007  *  modify it under the terms of the GNU Lesser General Public
    00008  *  License as published by the Free Software Foundation; either
    00009  *  version 2 of the License, or (at your option) any later version.
    00010  *
    00011  *  This library is distributed in the hope that it will be useful,
    00012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
    00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    00014  *  Lesser General Public License for more details.
    00015  *
    00016  *  You should have received a copy of the GNU Lesser General Public
    00017  *  License along with this library; if not, write to the Free Software
    00018  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    00019  *
    00020  */
    00021
    00022 #include <math.h>
    00023 #include <stdlib.h>
    00024 #include <stdio.h>
    00025 #include <assert.h>
    00026 #include <time.h>
    00027
    00028 #include "value.h"
    00029 #include "object.h"
    00030 #include "types.h"
    00031 #include "interpreter.h"
    00032 #include "operations.h"
    00033 #include "math_object.h"
    00034
    00035 #include "math_object.lut.h"
    00036
    00037 #ifndef M_PI
    00038 #define M_PI 3.14159265358979323846
    00039 #endif  /*  M_PI  */
    00040
    00041 using namespace KJS;
    00042
    00043 // ------------------------------ MathObjectImp --------------------------------
    00044
    00045 const ClassInfo MathObjectImp::info = { "Math", 0, &mathTable, 0 };
    00046
    00047 /* Source for math_object.lut.h
    00048 @begin mathTable 31
    00049   E             MathObjectImp::Euler    DontEnum|DontDelete|ReadOnly
    00050   LN2           MathObjectImp::Ln2      DontEnum|DontDelete|ReadOnly
    00051   LN10          MathObjectImp::Ln10     DontEnum|DontDelete|ReadOnly
    00052   LOG2E         MathObjectImp::Log2E    DontEnum|DontDelete|ReadOnly
    00053   LOG10E        MathObjectImp::Log10E   DontEnum|DontDelete|ReadOnly
    00054   PI            MathObjectImp::Pi       DontEnum|DontDelete|ReadOnly
    00055   SQRT1_2       MathObjectImp::Sqrt1_2  DontEnum|DontDelete|ReadOnly
    00056   SQRT2         MathObjectImp::Sqrt2    DontEnum|DontDelete|ReadOnly
    00057   abs           MathObjectImp::Abs      DontEnum|Function 1
    00058   acos          MathObjectImp::ACos     DontEnum|Function 1
    00059   asin          MathObjectImp::ASin     DontEnum|Function 1
    00060   atan          MathObjectImp::ATan     DontEnum|Function 1
    00061   atan2         MathObjectImp::ATan2    DontEnum|Function 2
    00062   ceil          MathObjectImp::Ceil     DontEnum|Function 1
    00063   cos           MathObjectImp::Cos      DontEnum|Function 1
    00064   exp           MathObjectImp::Exp      DontEnum|Function 1
    00065   floor         MathObjectImp::Floor    DontEnum|Function 1
    00066   log           MathObjectImp::Log      DontEnum|Function 1
    00067   max           MathObjectImp::Max      DontEnum|Function 2
    00068   min           MathObjectImp::Min      DontEnum|Function 2
    00069   pow           MathObjectImp::Pow      DontEnum|Function 2
    00070   random        MathObjectImp::Random   DontEnum|Function 0
    00071   round         MathObjectImp::Round    DontEnum|Function 1
    00072   sin           MathObjectImp::Sin      DontEnum|Function 1
    00073   sqrt          MathObjectImp::Sqrt     DontEnum|Function 1
    00074   tan           MathObjectImp::Tan      DontEnum|Function 1
    00075 @end
    00076 */
    00077
    00078 MathObjectImp::MathObjectImp(ExecState * /*exec*/,
    00079                              ObjectPrototypeImp *objProto)
    00080   : ObjectImp(objProto)
    00081 {
    00082    unsigned int seed = time(NULL);
    00083    ::srand(seed);
    00084 }
    00085
    00086 // ECMA 15.8
    00087 Value MathObjectImp::get(ExecState *exec, const Identifier &propertyName) const
    00088 {
    00089   return lookupGet<MathFuncImp, MathObjectImp, ObjectImp>( exec, propertyName, &mathTable, this );
    00090 }
    00091
    00092 Value MathObjectImp::getValueProperty(ExecState *, int token) const
    00093 {
    00094   double d = -42; // ;)
    00095   switch (token) {
    00096   case Euler:
    00097     d = exp(1.0);
    00098     break;
    00099   case Ln2:
    00100     d = log(2.0);
    00101     break;
    00102   case Ln10:
    00103     d = log(10.0);
    00104     break;
    00105   case Log2E:
    00106     d = 1.0/log(2.0);
    00107     break;
    00108   case Log10E:
    00109     d = 1.0/log(10.0);
    00110     break;
    00111   case Pi:
    00112     d = M_PI;
    00113     break;
    00114   case Sqrt1_2:
    00115     d = sqrt(0.5);
    00116     break;
    00117   case Sqrt2:
    00118     d = sqrt(2.0);
    00119     break;
    00120   default:
    00121     fprintf( stderr, "Internal error in MathObjectImp: unhandled token %d\n", token );
    00122     break;
    00123   }
    00124
    00125   return Number(d);
    00126 }
    00127
    00128 // ------------------------------ MathObjectImp --------------------------------
    00129
    00130 MathFuncImp::MathFuncImp(ExecState *exec, int i, int l)
    00131   : InternalFunctionImp(
    00132     static_cast<FunctionPrototypeImp*>(exec->interpreter()->builtinFunctionPrototype().imp())
    00133     ), id(i)
    00134 {
    00135   Value protect(this);
    00136   putDirect(lengthPropertyName, l, DontDelete|ReadOnly|DontEnum);
    00137 }
    00138
    00139 bool MathFuncImp::implementsCall() const
    00140 {
    00141   return true;
    00142 }
    00143
    00144 Value MathFuncImp::call(ExecState *exec, Object &/*thisObj*/, const List &args)
    00145 {
    00146   double arg = args[0].toNumber(exec);
    00147   double arg2 = args[1].toNumber(exec);
    00148   double result;
    00149
    00150   switch (id) {
    00151   case MathObjectImp::Abs:
    00152     result = ( arg < 0 || arg == -0) ? (-arg) : arg;
    00153     break;
    00154   case MathObjectImp::ACos:
    00155     result = ::acos(arg);
    00156     break;
    00157   case MathObjectImp::ASin:
    00158     result = ::asin(arg);
    00159     break;
    00160   case MathObjectImp::ATan:
    00161     result = ::atan(arg);
    00162     break;
    00163   case MathObjectImp::ATan2:
    00164     result = ::atan2(arg, arg2);
    00165     break;
    00166   case MathObjectImp::Ceil:
    00167     result = ::ceil(arg);
    00168     break;
    00169   case MathObjectImp::Cos:
    00170     result = ::cos(arg);
    00171     break;
    00172   case MathObjectImp::Exp:
    00173     result = ::exp(arg);
    00174     break;
    00175   case MathObjectImp::Floor:
    00176     result = ::floor(arg);
    00177     break;
    00178   case MathObjectImp::Log:
    00179     result = ::log(arg);
    00180     break;
    00181   case MathObjectImp::Max: {
    00182     unsigned int argsCount = args.size();
    00183     result = -Inf;
    00184     for ( unsigned int k = 0 ; k < argsCount ; ++k ) {
    00185       double val = args[k].toNumber(exec);
    00186       if ( isNaN( val ) )
    00187       {
    00188         result = NaN;
    00189         break;
    00190       }
    00191       if ( val > result )
    00192         result = val;
    00193     }
    00194     break;
    00195   }
    00196   case MathObjectImp::Min: {
    00197     unsigned int argsCount = args.size();
    00198     result = +Inf;
    00199     for ( unsigned int k = 0 ; k < argsCount ; ++k ) {
    00200       double val = args[k].toNumber(exec);
    00201       if ( isNaN( val ) )
    00202       {
    00203         result = NaN;
    00204         break;
    00205       }
    00206       if ( val < result || (result == 0 && IS_NEGATIVE_ZERO(val)) )
    00207         result = val;
    00208     }
    00209     break;
    00210   }
    00211   case MathObjectImp::Pow:
    00212     // ECMA 15.8.2.1.13 (::pow takes care of most of the critera)
    00213     if (KJS::isNaN(arg2))
    00214       result = NaN;
    00215     else if (arg2 == 0)
    00216       result = 1;
    00217     else if (KJS::isNaN(arg) && arg2 != 0)
    00218       result = NaN;
    00219     else if (::fabs(arg) > 1 && KJS::isPosInf(arg2))
    00220       result = Inf;
    00221     else if (::fabs(arg) > 1 && KJS::isNegInf(arg2))
    00222       result = +0;
    00223     else if (::fabs(arg) == 1 && KJS::isPosInf(arg2))
    00224       result = NaN;
    00225     else if (::fabs(arg) == 1 && KJS::isNegInf(arg2))
    00226       result = NaN;
    00227     else if (::fabs(arg) < 1 && KJS::isPosInf(arg2))
    00228       result = +0;
    00229     else if (::fabs(arg) < 1 && KJS::isNegInf(arg2))
    00230       result = Inf;
    00231     else
    00232       result = ::pow(arg, arg2);
    00233     break;
    00234   case MathObjectImp::Random:
    00235     result = ::rand();
    00236     result = result / RAND_MAX;
    00237     break;
    00238   case MathObjectImp::Round:
    00239     if (arg < 0 && arg >= -0.5)
    00240       result = -0.0;
    00241     else if (IS_NEGATIVE_ZERO(arg))
    00242       result = arg;
    00243     else
    00244       result = ::floor(arg + 0.5);
    00245     break;
    00246   case MathObjectImp::Sin:
    00247     result = ::sin(arg);
    00248     break;
    00249   case MathObjectImp::Sqrt:
    00250     result = ::sqrt(arg);
    00251     break;
    00252   case MathObjectImp::Tan:
    00253     result = ::tan(arg);
    00254     break;
    00255
    00256   default:
    00257     result = 0.0;
    00258     assert(0);
    00259   }
    00260
    00261   return Number(result);
    00262 }

This file is part of the documentation for kjs Library Version 3.4.1.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sat Jun 11 20:23:06 2005 by doxygen 1.4.1 written by Dimitri van Heesch, © 1997-2003