KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > quercus > lib > MathModule


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  *
23  * Free Software Foundation, Inc.
24  * 59 Temple Place, Suite 330
25  * Boston, MA 02111-1307 USA
26  *
27  * @author Scott Ferguson
28  */

29
30 package com.caucho.quercus.lib;
31
32 import com.caucho.quercus.annotation.Optional;
33 import com.caucho.quercus.env.*;
34 import com.caucho.quercus.module.AbstractQuercusModule;
35 import com.caucho.util.L10N;
36 import com.caucho.util.RandomUtil;
37
38 /**
39  * PHP math routines.
40  */

41 public class MathModule extends AbstractQuercusModule {
42   private static final L10N L = new L10N(MathModule.class);
43
44   public static final double M_PI = Math.PI;
45   public static final double M_E = Math.E;
46
47   public static final long RAND_MAX = Integer.MAX_VALUE;
48
49   public static final double M_LOG2E = log2(Math.E);
50   public static final double M_LOG10E = Math.log10(Math.E);
51   public static final double M_LN2 = Math.log(2);
52   public static final double M_LN10 = Math.log(10);
53   public static final double M_PI_2 = Math.PI / 2;
54   public static final double M_PI_4 = Math.PI / 4;
55   public static final double M_1_PI = 1 / Math.PI;
56   public static final double M_2_PI = 2 / Math.PI;
57   public static final double M_SQRTPI = Math.sqrt(Math.PI);
58   public static final double M_2_SQRTPI = 2 / Math.sqrt(Math.PI);
59   public static final double M_SQRT2 = Math.sqrt(2);
60   public static final double M_SQRT3 = Math.sqrt(3);
61   public static final double M_SQRT1_2 = 1 / Math.sqrt(2);
62   public static final double M_LNPI = Math.log(Math.PI);
63   public static final double M_EULER = 0.57721566490153286061;
64
65   private static double log2(double v)
66   {
67     return Math.log(v) / Math.log(2);
68   }
69
70   public static Value abs(Value value)
71   {
72     if (value instanceof DoubleValue)
73       return new DoubleValue(Math.abs(value.toDouble()));
74     else
75       return new LongValue(Math.abs(value.toLong()));
76   }
77
78   public static double acos(double value)
79   {
80     return Math.acos(value);
81   }
82
83   public static Value acosh(Env env, Value value)
84   {
85     throw new UnsupportedOperationException JavaDoc();
86   }
87
88   public static Value asin(Value value)
89   {
90     return new DoubleValue(Math.asin(value.toDouble()));
91   }
92
93   public static Value asinh(Value value)
94   {
95     throw new UnsupportedOperationException JavaDoc();
96   }
97
98   public static double atan2(double yV, double xV)
99   {
100     return Math.atan2(yV, xV);
101   }
102
103   public static double atan(double value)
104   {
105     return Math.atan(value);
106   }
107
108   public static Value atanh(Value value)
109   {
110     throw new UnsupportedOperationException JavaDoc();
111   }
112
113   public static Value base_convert(Env env, String JavaDoc number, int fromBase, int toBase)
114   {
115     if (fromBase < 2 || fromBase > 36) {
116       env.warning(L.l("invalid `{0}' ({1})", "from base", fromBase));
117       return BooleanValue.FALSE;
118     }
119
120     if (toBase < 2 || toBase > 36) {
121       env.warning(L.l("invalid `{0}' ({1})", "to base", toBase));
122       return BooleanValue.FALSE;
123     }
124
125     long result = 0;
126
127     int len = number.length();
128
129     for (int i = 0; i < len; i++) {
130       int ch = number.charAt(i);
131
132       int value;
133
134       if ('0' <= ch && ch <= '9')
135         value = ch - '0';
136       else if ('a' <= ch && ch <= 'z')
137         value = ch - 'a' + 10;
138       else if ('A' <= ch && ch <= 'Z')
139         value = ch - 'a' + 10;
140       else
141         continue;
142
143       if (fromBase <= value)
144         continue;
145
146       result = result * fromBase;
147
148       result += value;
149     }
150
151     if (result == 0)
152       return new StringValueImpl("0");
153
154     StringBuilder JavaDoc sb = new StringBuilder JavaDoc();
155
156     do {
157       int d = (int) (result % toBase);
158       result = result / toBase;
159
160       if (d < 10)
161         sb.append((char) (d + '0'));
162       else
163         sb.append((char) (d - 10 + 'a'));
164     } while (result != 0);
165
166     sb.reverse();
167
168     return new StringValueImpl(sb.toString());
169   }
170
171   /**
172    * Returns the long value of an binary number.
173    *
174    * @param bin A string represeantion of an binary number.
175    * @return the decimal equivalent of the binary number
176    * @throws ArithmeticException if the binary number cannot fit in a long
177    */

178   public static long bindec(StringValue bin)
179   {
180     // This implementation deliberately differs from the php implementation,
181
// which returns an int or a float. Quercus uses long's to represent
182
// integral values and the long represenation is more accurate than a float.
183
long result = 0;
184
185     int len = bin.length();
186
187     for (int i = 0; i < len; i++) {
188       char ch = bin.charAt(i);
189
190       if ('0' == ch)
191         result = 2 * result;
192       else if ('1' == ch) {
193         result = 2 * result;
194         result += 1;
195       }
196
197       if (result < 0)
198         throw new ArithmeticException JavaDoc(L.l("overflow"));
199     }
200
201     return result;
202   }
203
204   public static double ceil(double value)
205   {
206     return Math.ceil(value);
207   }
208
209   public static double cos(double value)
210   {
211     return Math.cos(value);
212   }
213
214   public static double cosh(double value)
215   {
216     return Math.cosh(value);
217   }
218
219   /**
220    * Returns a binary representation of a number.
221    * @param value the number
222    */

223   public static String JavaDoc decbin(long value)
224   {
225     if (value == 0)
226       return "0";
227
228     StringBuilder JavaDoc sb = new StringBuilder JavaDoc();
229
230     while (value != 0) {
231       int d = (int) (value & 1);
232       value = value / 2;
233
234       if (d == 0)
235         sb.append('0');
236       else
237         sb.append('1');
238     }
239
240     sb.reverse();
241
242     return sb.toString();
243   }
244
245   /**
246    * Returns a hexadecimal representation of a number.
247    * @param value the number
248    */

249   public static String JavaDoc dechex(long value)
250   {
251     if (value == 0)
252       return "0";
253
254     StringBuilder JavaDoc sb = new StringBuilder JavaDoc();
255
256     while (value != 0) {
257       int d = (int) (value & 0xf);
258       value = value / 16;
259
260       if (d < 10)
261         sb.append((char) (d + '0'));
262       else
263         sb.append((char) (d + 'a' - 10));
264     }
265
266     sb.reverse();
267
268     return sb.toString();
269   }
270
271   /**
272    * Returns an octal representation of a number.
273    * @param value the number
274    */

275   public static String JavaDoc decoct(long value)
276   {
277     if (value == 0)
278       return "0";
279
280     StringBuilder JavaDoc sb = new StringBuilder JavaDoc();
281
282     while (value != 0) {
283       int d = (int) (value & 7);
284       value = value / 8;
285
286       sb.append((char) (d + '0'));
287     }
288
289     sb.reverse();
290
291     return sb.toString();
292   }
293
294   public static double deg2rad(double value)
295   {
296     return value * Math.PI / 180;
297   }
298
299   public static Value exp(Value value)
300   {
301     return new DoubleValue(Math.exp(value.toDouble()));
302   }
303
304   public static Value expm1(Value value)
305   {
306     return new DoubleValue(Math.expm1(value.toDouble()));
307   }
308
309   public static Value floor(Value value)
310   {
311     return new DoubleValue(Math.floor(value.toDouble()));
312   }
313
314   public static double fmod(double xV, double yV)
315   {
316     return Math.IEEEremainder(xV, yV);
317   }
318
319   public static long hexdec(StringValue s)
320   {
321     long v = 0;
322     int len = s.length();
323
324     for (int i = 0; i < len; i++) {
325       char ch = s.charAt(i);
326
327       if ('0' <= ch && ch <= '9')
328         v = 16 * v + ch - '0';
329       else if ('a' <= ch && ch <= 'f')
330         v = 16 * v + ch - 'a' + 10;
331       else if ('A' <= ch && ch <= 'F')
332         v = 16 * v + ch - 'A' + 10;
333     }
334
335     return v;
336   }
337
338   public static double hypot(double a, double b)
339   {
340     return Math.hypot(a, b);
341   }
342
343   public static boolean is_finite(Value value)
344   {
345     if (value instanceof LongValue)
346       return true;
347     else if (value instanceof DoubleValue) {
348       double v = value.toDouble();
349
350       return ! Double.isInfinite(v);
351     }
352     else
353       return false;
354   }
355
356   public static Value is_infinite(Value value)
357   {
358     if (value instanceof LongValue)
359       return BooleanValue.FALSE;
360     else if (value instanceof DoubleValue) {
361       double v = value.toDouble();
362
363       return Double.isInfinite(v) ? BooleanValue.TRUE : BooleanValue.FALSE;
364     }
365     else
366       return BooleanValue.FALSE;
367   }
368
369   public static Value is_nan(Value value)
370   {
371     if (value instanceof LongValue)
372       return BooleanValue.FALSE;
373     else if (value instanceof DoubleValue) {
374       double v = value.toDouble();
375
376       return Double.isNaN(v) ? BooleanValue.TRUE : BooleanValue.FALSE;
377     }
378     else
379       return BooleanValue.FALSE;
380   }
381
382   public static double log(double value)
383   {
384     return Math.log(value);
385   }
386
387   public static double log10(double value)
388   {
389     return Math.log10(value);
390   }
391
392   public static double log1p(double value)
393   {
394     return Math.log1p(value);
395   }
396
397   public static Value getrandmax()
398   {
399     return mt_getrandmax();
400   }
401
402   public static Value max(Value []args)
403   {
404     if (args.length == 1 && args[0] instanceof ArrayValue) {
405       Value array = args[0];
406       Value max = NullValue.NULL;
407       double maxValue = Double.MIN_VALUE;
408
409       for (Value key : array.getIndices()) {
410         Value value = array.get(key);
411         double dValue = value.toDouble();
412
413         if (maxValue < dValue) {
414           maxValue = dValue;
415           max = value;
416         }
417       }
418
419       return max;
420     }
421     else {
422       double maxValue = - Double.MAX_VALUE;
423       Value max = NullValue.NULL;
424
425       for (int i = 0; i < args.length; i++) {
426         double value = args[i].toDouble();
427
428         if (maxValue < value) {
429           maxValue = value;
430           max = args[i];
431         }
432       }
433
434       return max;
435     }
436   }
437
438   public static Value min(Value []args)
439   {
440     if (args.length == 1 && args[0] instanceof ArrayValue) {
441       Value array = args[0];
442       Value min = NullValue.NULL;
443       double minValue = Double.MAX_VALUE;
444
445       for (Value key : array.getIndices()) {
446         Value value = array.get(key);
447         double dValue = value.toDouble();
448
449         if (dValue < minValue) {
450           minValue = dValue;
451           min = value;
452         }
453       }
454
455       return min;
456     }
457     else {
458       double minValue = Double.MAX_VALUE;
459       Value min = NullValue.NULL;
460
461       for (int i = 0; i < args.length; i++) {
462         double value = args[i].toDouble();
463
464         if (value < minValue) {
465           minValue = value;
466           min = args[i];
467         }
468       }
469
470       return min;
471     }
472   }
473
474   public static Value mt_getrandmax()
475   {
476     return new LongValue(RAND_MAX);
477   }
478
479   public static long mt_rand(@Optional("0") long min,
480                              @Optional("RAND_MAX") long max)
481   {
482     long range = max - min + 1;
483
484     if (range <= 0)
485       return min;
486
487     long value = RandomUtil.getRandomLong();
488     if (value < 0)
489       value = - value;
490
491     return min + value % range;
492   }
493
494   public static Value mt_srand(@Optional long seed)
495   {
496     return NullValue.NULL;
497   }
498
499   /**
500    * Returns the long value of an octal number.
501    *
502    * @param oct A string represeantion of an octal number.
503    * @return the decimal equivalent of the octal number
504    * @throws ArithmeticException if the octal number cannot fit in a long
505    */

506   public static long octdec(StringValue oct)
507   {
508     // This implementation deliberately differs from the php implementation,
509
// which returns an int or a float. Quercus uses long's to represent
510
// integral values and the long represenation is more accurate than a float.
511
long result = 0;
512
513     int len = oct.length();
514
515     for (int i = 0; i < len; i++) {
516       int ch = oct.charAt(i);
517
518       if ('0' <= ch && ch <= '7') {
519         result = result << 3;
520         result += ch - '0';
521
522         if (result < 0)
523           throw new ArithmeticException JavaDoc(L.l("overflow"));
524       }
525     }
526
527     return result;
528   }
529
530
531   public static double pi()
532   {
533     return M_PI;
534   }
535
536   public static double pow(double base, double exp)
537   {
538     return Math.pow(base, exp);
539   }
540
541   public static double rad2deg(double value)
542   {
543     return 180 * value / Math.PI;
544   }
545
546   public static long rand(@Optional int min,
547               @Optional("RAND_MAX") int max)
548   {
549     return mt_rand(min, max);
550   }
551
552   public static double round(double value, @Optional int precision)
553   {
554     if (precision > 0) {
555       double exp = Math.pow(10, precision);
556
557       return Math.round(value * exp) / exp;
558     }
559     else
560       return Math.round(value);
561   }
562
563   public static double sin(double value)
564   {
565     return Math.sin(value);
566   }
567
568   public static Value sinh(Value value)
569   {
570     return new DoubleValue(Math.sinh(value.toDouble()));
571   }
572
573   public static double sqrt(double value)
574   {
575     return Math.sqrt(value);
576   }
577
578   public static Value srand(@Optional long seed)
579   {
580     return NullValue.NULL;
581   }
582
583   public static double tan(double value)
584   {
585     return Math.tan(value);
586   }
587
588   public static double tanh(double value)
589   {
590     return Math.tanh(value);
591   }
592 }
593
Popular Tags