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 00027 #include "value.h" 00028 #include "object.h" 00029 #include "types.h" 00030 #include "interpreter.h" 00031 #include "operations.h" 00032 #include "math_object.h" 00033 00034 #include "math_object.lut.h" 00035 00036 #ifndef M_PI 00037 #define M_PI 3.14159265358979323846 00038 #endif /* M_PI */ 00039 00040 using namespace KJS; 00041 00042 // ------------------------------ MathObjectImp -------------------------------- 00043 00044 const ClassInfo MathObjectImp::info = { "Math", 0, &mathTable, 0 }; 00045 00046 /* Source for math_object.lut.h 00047 @begin mathTable 31 00048 E MathObjectImp::Euler DontEnum|DontDelete|ReadOnly 00049 LN2 MathObjectImp::Ln2 DontEnum|DontDelete|ReadOnly 00050 LN10 MathObjectImp::Ln10 DontEnum|DontDelete|ReadOnly 00051 LOG2E MathObjectImp::Log2E DontEnum|DontDelete|ReadOnly 00052 LOG10E MathObjectImp::Log10E DontEnum|DontDelete|ReadOnly 00053 PI MathObjectImp::Pi DontEnum|DontDelete|ReadOnly 00054 SQRT1_2 MathObjectImp::Sqrt1_2 DontEnum|DontDelete|ReadOnly 00055 SQRT2 MathObjectImp::Sqrt2 DontEnum|DontDelete|ReadOnly 00056 abs MathObjectImp::Abs DontEnum|Function 1 00057 acos MathObjectImp::ACos DontEnum|Function 1 00058 asin MathObjectImp::ASin DontEnum|Function 1 00059 atan MathObjectImp::ATan DontEnum|Function 1 00060 atan2 MathObjectImp::ATan2 DontEnum|Function 2 00061 ceil MathObjectImp::Ceil DontEnum|Function 1 00062 cos MathObjectImp::Cos DontEnum|Function 1 00063 exp MathObjectImp::Exp DontEnum|Function 1 00064 floor MathObjectImp::Floor DontEnum|Function 1 00065 log MathObjectImp::Log DontEnum|Function 1 00066 max MathObjectImp::Max DontEnum|Function 2 00067 min MathObjectImp::Min DontEnum|Function 2 00068 pow MathObjectImp::Pow DontEnum|Function 2 00069 random MathObjectImp::Random DontEnum|Function 0 00070 round MathObjectImp::Round DontEnum|Function 1 00071 sin MathObjectImp::Sin DontEnum|Function 1 00072 sqrt MathObjectImp::Sqrt DontEnum|Function 1 00073 tan MathObjectImp::Tan DontEnum|Function 1 00074 @end 00075 */ 00076 00077 MathObjectImp::MathObjectImp(ExecState * /*exec*/, 00078 ObjectPrototypeImp *objProto) 00079 : ObjectImp(objProto) 00080 { 00081 } 00082 00083 // ECMA 15.8 00084 Value MathObjectImp::get(ExecState *exec, const Identifier &propertyName) const 00085 { 00086 return lookupGet<MathFuncImp, MathObjectImp, ObjectImp>( exec, propertyName, &mathTable, this ); 00087 } 00088 00089 Value MathObjectImp::getValueProperty(ExecState *, int token) const 00090 { 00091 double d = -42; // ;) 00092 switch (token) { 00093 case Euler: 00094 d = exp(1.0); 00095 break; 00096 case Ln2: 00097 d = log(2.0); 00098 break; 00099 case Ln10: 00100 d = log(10.0); 00101 break; 00102 case Log2E: 00103 d = 1.0/log(2.0); 00104 break; 00105 case Log10E: 00106 d = 1.0/log(10.0); 00107 break; 00108 case Pi: 00109 d = M_PI; 00110 break; 00111 case Sqrt1_2: 00112 d = sqrt(0.5); 00113 break; 00114 case Sqrt2: 00115 d = sqrt(2.0); 00116 break; 00117 default: 00118 fprintf( stderr, "Internal error in MathObjectImp: unhandled token %d\n", token ); 00119 break; 00120 } 00121 00122 return Number(d); 00123 } 00124 00125 // ------------------------------ MathObjectImp -------------------------------- 00126 00127 MathFuncImp::MathFuncImp(ExecState *exec, int i, int l) 00128 : InternalFunctionImp( 00129 static_cast<FunctionPrototypeImp*>(exec->interpreter()->builtinFunctionPrototype().imp()) 00130 ), id(i) 00131 { 00132 Value protect(this); 00133 putDirect(lengthPropertyName, l, DontDelete|ReadOnly|DontEnum); 00134 } 00135 00136 bool MathFuncImp::implementsCall() const 00137 { 00138 return true; 00139 } 00140 00141 Value MathFuncImp::call(ExecState *exec, Object &/*thisObj*/, const List &args) 00142 { 00143 double arg = args[0].toNumber(exec); 00144 double arg2 = args[1].toNumber(exec); 00145 double result; 00146 00147 switch (id) { 00148 case MathObjectImp::Abs: 00149 result = ( arg < 0 || arg == -0) ? (-arg) : arg; 00150 break; 00151 case MathObjectImp::ACos: 00152 result = ::acos(arg); 00153 break; 00154 case MathObjectImp::ASin: 00155 result = ::asin(arg); 00156 break; 00157 case MathObjectImp::ATan: 00158 result = ::atan(arg); 00159 break; 00160 case MathObjectImp::ATan2: 00161 result = ::atan2(arg, arg2); 00162 break; 00163 case MathObjectImp::Ceil: 00164 result = ::ceil(arg); 00165 break; 00166 case MathObjectImp::Cos: 00167 result = ::cos(arg); 00168 break; 00169 case MathObjectImp::Exp: 00170 result = ::exp(arg); 00171 break; 00172 case MathObjectImp::Floor: 00173 result = ::floor(arg); 00174 break; 00175 case MathObjectImp::Log: 00176 result = ::log(arg); 00177 break; 00178 case MathObjectImp::Max: { 00179 unsigned int argsCount = args.size(); 00180 result = -Inf; 00181 for ( unsigned int k = 0 ; k < argsCount ; ++k ) { 00182 double val = args[k].toNumber(exec); 00183 if ( isNaN( val ) ) 00184 { 00185 result = NaN; 00186 break; 00187 } 00188 if ( val > result ) 00189 result = val; 00190 } 00191 break; 00192 } 00193 case MathObjectImp::Min: { 00194 unsigned int argsCount = args.size(); 00195 result = +Inf; 00196 for ( unsigned int k = 0 ; k < argsCount ; ++k ) { 00197 double val = args[k].toNumber(exec); 00198 if ( isNaN( val ) ) 00199 { 00200 result = NaN; 00201 break; 00202 } 00203 if ( val < result || (result == 0 && IS_NEGATIVE_ZERO(val)) ) 00204 result = val; 00205 } 00206 break; 00207 } 00208 case MathObjectImp::Pow: 00209 // ECMA 15.8.2.1.13 (::pow takes care of most of the critera) 00210 if (KJS::isNaN(arg2)) 00211 result = NaN; 00212 else if (arg2 == 0) 00213 result = 1; 00214 else if (KJS::isNaN(arg) && arg2 != 0) 00215 result = NaN; 00216 else if (::fabs(arg) > 1 && KJS::isPosInf(arg2)) 00217 result = Inf; 00218 else if (::fabs(arg) > 1 && KJS::isNegInf(arg2)) 00219 result = +0; 00220 else if (::fabs(arg) == 1 && KJS::isPosInf(arg2)) 00221 result = NaN; 00222 else if (::fabs(arg) == 1 && KJS::isNegInf(arg2)) 00223 result = NaN; 00224 else if (::fabs(arg) < 1 && KJS::isPosInf(arg2)) 00225 result = +0; 00226 else if (::fabs(arg) < 1 && KJS::isNegInf(arg2)) 00227 result = Inf; 00228 else 00229 result = ::pow(arg, arg2); 00230 break; 00231 case MathObjectImp::Random: 00232 result = ::rand(); 00233 result = result / RAND_MAX; 00234 break; 00235 case MathObjectImp::Round: 00236 if (arg < 0 && arg >= -0.5) 00237 result = -0.0; 00238 else if (IS_NEGATIVE_ZERO(arg)) 00239 result = arg; 00240 else 00241 result = ::floor(arg + 0.5); 00242 break; 00243 case MathObjectImp::Sin: 00244 result = ::sin(arg); 00245 break; 00246 case MathObjectImp::Sqrt: 00247 result = ::sqrt(arg); 00248 break; 00249 case MathObjectImp::Tan: 00250 result = ::tan(arg); 00251 break; 00252 00253 default: 00254 result = 0.0; 00255 assert(0); 00256 } 00257 00258 return Number(result); 00259 }
KDE Logo
This file is part of the documentation for kjs Library Version 3.2.3.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sun Oct 10 18:55:17 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003