001 
002 /*
003  *  Descripter 1.0 - Java Script Engines
004  *  Copyright (C) 2010-2015  Jianjun Liu (J.J.Liu)
005  *  
006  *  This program is free software: you can redistribute it and/or modify
007  *  it under the terms of the GNU Affero General Public License as published by
008  *  the Free Software Foundation, either version 3 of the License, or
009  *  (at your option) any later version.
010  *  
011  *  This program is distributed in the hope that it will be useful,
012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
014  *  GNU Affero General Public License for more details.
015  *  
016  *  You should have received a copy of the GNU Affero General Public License
017  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
018  */
019 
020 package org.descripter.js.api.core;
021 
022 import org.descripter.js.api.Core;
023 import org.descripter.js.api.Function;
024 import org.descripter.js.api.Functor;
025 
026 /**
027  * <p>Emulates the JavaScript Math object.</p>
028  * 
029  * @author <a href="mailto:jianjunliu@126.com">J.J.Liu (Jianjun Liu)</a> at <a href="http://www.descripter.org" target="_blank">http://www.descripter.org</a>
030  * @since Descripter 1.0
031  */
032 public class CMath extends CObject
033 {
034     /**
035      * The constant e, the base of the natural logarithm.
036      * @since Descripter 1.0
037      */
038     public final static double E       = Math.E;
039     /**
040      * The natural logarithm of 2.
041      * @since Descripter 1.0
042      */
043     public final static double LN2     = Math.log(2);
044     /**
045      * The natural logarithm of 10.
046      * @since Descripter 1.0
047      */
048     public final static double LN10    = Math.log(10);
049     /**
050      * The base-2 logarithm of e.
051      * @since Descripter 1.0
052      */
053     public final static double LOG2E   = 1 / LN2;
054     /**
055      * The base-10 logarithm of e.
056      * @since Descripter 1.0
057      */
058     public final static double LOG10E  = 1 / LN10;
059     /**
060      * The constant pi, the ratio of the circumference of a circle to its diameter. 
061      * It has a value of approximately 3.14159265358979.
062      * @since Descripter 1.0
063      */
064     public final static double PI      = Math.PI;
065     /**
066      * The square root of 2.
067      * @since Descripter 1.0
068      */
069     public final static double SQRT2   = Math.sqrt(2);
070     /**
071      * The reciprocal of the square root of 2, that is, 
072      * the number 1 divided by the square root of 2.
073      * @since Descripter 1.0
074      */
075     public final static double SQRT1_2 = 1 / SQRT2;
076 
077     /**
078      * <p>Creates the singleton of the global object of this type.</p>
079      * @param core The {@link Core} global script context
080      * @since Descripter 1.0
081      */
082     public static final void create(Core core) {
083         if (core.get(core._Math) == null) {
084             core.put(core._Math, new CMath(core));
085         }
086     }
087 
088     /**
089      * <p>Returns the largest of the arguments.</p>
090      * @param args An array of arguments.
091      * @return The largest of the arguments
092      * @since Descripter 1.0
093      */
094     public final Number max(CArray args) {
095         double m = doubleValue(args.get(0));
096         for (int i = 1, len = args.length(); i < len; i++) {
097             m = Math.max(m, doubleValue(args.get(i)));
098         }
099         return m;
100     }
101 
102     /**
103      * <p>Returns the smallest of the arguments.</p>
104      * @param args An array of arguments.
105      * @return The smallest of the arguments
106      * @since Descripter 1.0
107      */
108     public final Number min(CArray args) {
109         double m = doubleValue(args.get(0));
110         for (int i = 1, len = args.length(); i < len; i++) {
111             m = Math.min(m, doubleValue(args.get(i)));
112         }
113         return m;
114     }
115 
116     private CMath(Core core) {
117         super(core._Object());
118         put(core._E      , E);
119         put(core._LN10   , LN10);
120         put(core._LN2    , LN2);
121         put(core._LOG10E , LOG10E);
122         put(core._LOG2E  , LOG2E);
123         put(core._PI     , PI);
124         put(core._SQRT1_2, SQRT1_2);
125         put(core._SQRT2  , SQRT2);
126         put(core._abs, new Function<Core>(core) {
127             @Override
128             public Functor<Core> functor() {
129                 return new Functor<Core>(this) {
130                     @Override
131                     public Object function() {
132                         return Math.abs(doubleValue(arguments().get(0)));
133                     }
134                 };
135             }
136         });
137         put(core._acos, new Function<Core>(core) {
138             @Override
139             public Functor<Core> functor() {
140                 return new Functor<Core>(this) {
141                     @Override
142                     public Object function() {
143                         return Math.acos(doubleValue(arguments().get(0)));
144                     }
145                 };
146             }
147         });
148         put(core._asin, new Function<Core>(core) {
149             @Override
150             public Functor<Core> functor() {
151                 return new Functor<Core>(this) {
152                     @Override
153                     public Object function() {
154                         return Math.asin(doubleValue(arguments().get(0)));
155                     }
156                 };
157             }
158         });
159         put(core._atan, new Function<Core>(core) {
160             @Override
161             public Functor<Core> functor() {
162                 return new Functor<Core>(this) {
163                     @Override
164                     public Object function() {
165                         return Math.atan(doubleValue(arguments().get(0)));
166                     }
167                 };
168             }
169         });
170         put(core._atan2, new Function<Core>(core) {
171             @Override
172             public Functor<Core> functor() {
173                 return new Functor<Core>(this) {
174                     @Override
175                     public Object function() {
176                         return Math.atan2(doubleValue(arguments().get(0)), doubleValue(arguments().get(1)));
177                     }
178                 };
179             }
180         });
181         put(core._ceil, new Function<Core>(core) {
182             @Override
183             public Functor<Core> functor() {
184                 return new Functor<Core>(this) {
185                     @Override
186                     public Object function() {
187                         return Math.ceil(doubleValue(arguments().get(0)));
188                     }
189                 };
190             }
191         });
192         put(core._cos, new Function<Core>(core) {
193             @Override
194             public Functor<Core> functor() {
195                 return new Functor<Core>(this) {
196                     @Override
197                     public Object function() {
198                         return Math.cos(doubleValue(arguments().get(0)));
199                     }
200                 };
201             }
202         });
203         put(core._exp, new Function<Core>(core) {
204             @Override
205             public Functor<Core> functor() {
206                 return new Functor<Core>(this) {
207                     @Override
208                     public Object function() {
209                         return Math.exp(doubleValue(arguments().get(0)));
210                     }
211                 };
212             }
213         });
214         put(core._floor, new Function<Core>(core) {
215             @Override
216             public Functor<Core> functor() {
217                 return new Functor<Core>(this) {
218                     @Override
219                     public Object function() {
220                         return Math.floor(doubleValue(arguments().get(0)));
221                     }
222                 };
223             }
224         });
225         put(core._max, new Function<Core>(core) {
226             @Override
227             public Functor<Core> functor() {
228                 return new Functor<Core>(this) {
229                     @Override
230                     public Object function() {
231                         return CMath.this.max(arguments());
232                     }
233                 };
234             }
235         });
236         put(core._min, new Function<Core>(core) {
237             @Override
238             public Functor<Core> functor() {
239                 return new Functor<Core>(this) {
240                     @Override
241                     public Object function() {
242                         return CMath.this.min(arguments());
243                     }
244                 };
245             }
246         });
247         put(core._log, new Function<Core>(core) {
248             @Override
249             public Functor<Core> functor() {
250                 return new Functor<Core>(this) {
251                     @Override
252                     public Object function() {
253                         return Math.log(doubleValue(arguments().get(0)));
254                     }
255                 };
256             }
257         });
258         put(core._pow, new Function<Core>(core) {
259             @Override
260             public Functor<Core> functor() {
261                 return new Functor<Core>(this) {
262                     @Override
263                     public Object function() {
264                         return Math.pow(doubleValue(arguments().get(0)), doubleValue(arguments().get(1)));
265                     }
266                 };
267             }
268         });
269         put(core._random, new Function<Core>(core) {
270             @Override
271             public Functor<Core> functor() {
272                 return new Functor<Core>(this) {
273                     @Override
274                     public Object function() {
275                         return Math.random();
276                     }
277                 };
278             }
279         });
280         put(core._round, new Function<Core>(core) {
281             @Override
282             public Functor<Core> functor() {
283                 return new Functor<Core>(this) {
284                     @Override
285                     public Object function() {
286                         return Math.round(doubleValue(arguments().get(0)));
287                     }
288                 };
289             }
290         });
291         put(core._sin, new Function<Core>(core) {
292             @Override
293             public Functor<Core> functor() {
294                 return new Functor<Core>(this) {
295                     @Override
296                     public Object function() {
297                         return Math.sin(doubleValue(arguments().get(0)));
298                     }
299                 };
300             }
301         });
302         put(core._sinh, new Function<Core>(core) {
303             @Override
304             public Functor<Core> functor() {
305                 return new Functor<Core>(this) {
306                     @Override
307                     public Object function() {
308                         return Math.sinh(doubleValue(arguments().get(0)));
309                     }
310                 };
311             }
312         });
313         put(core._sqrt, new Function<Core>(core) {
314             @Override
315             public Functor<Core> functor() {
316                 return new Functor<Core>(this) {
317                     @Override
318                     public Object function() {
319                         return Math.sqrt(doubleValue(arguments().get(0)));
320                     }
321                 };
322             }
323         });
324         put(core._tan, new Function<Core>(core) {
325             @Override
326             public Functor<Core> functor() {
327                 return new Functor<Core>(this) {
328                     @Override
329                     public Object function() {
330                         return Math.tan(doubleValue(arguments().get(0)));
331                     }
332                 };
333             }
334         });
335         put(core._tanh, new Function<Core>(core) {
336             @Override
337             public Functor<Core> functor() {
338                 return new Functor<Core>(this) {
339                     @Override
340                     public Object function() {
341                         return Math.tanh(doubleValue(arguments().get(0)));
342                     }
343                 };
344             }
345         });
346     }
347 }