kjs Library API Documentation

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 }
KDE Logo
This file is part of the documentation for kjs Library Version 3.3.1.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sun Oct 17 11:28:50 2004 by doxygen 1.3.8 written by Dimitri van Heesch, © 1997-2003