1 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 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 (); 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 (); 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 (); 111 } 112 113 public static Value base_convert(Env env, String 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 sb = new StringBuilder (); 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 178 public static long bindec(StringValue bin) 179 { 180 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 (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 223 public static String decbin(long value) 224 { 225 if (value == 0) 226 return "0"; 227 228 StringBuilder sb = new StringBuilder (); 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 249 public static String dechex(long value) 250 { 251 if (value == 0) 252 return "0"; 253 254 StringBuilder sb = new StringBuilder (); 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 275 public static String decoct(long value) 276 { 277 if (value == 0) 278 return "0"; 279 280 StringBuilder sb = new StringBuilder (); 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 506 public static long octdec(StringValue oct) 507 { 508 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 (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 |