00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "copyright.h"
00010 #include "autoconf.h"
00011 #include "config.h"
00012 #include "externs.h"
00013
00014 #include <float.h>
00015 #include <limits.h>
00016 #include <math.h>
00017
00018 #include "functions.h"
00019 #include "funmath.h"
00020 #include "sha1.h"
00021
00022 #ifdef HAVE_IEEE_FP_FORMAT
00023
00024 static const char *mux_FPStrings[] = { "+Inf", "-Inf", "Ind", "NaN", "0", "0", "0", "0" };
00025
00026 #define MUX_FPGROUP_PASS 0x00 // Pass-through to printf
00027 #define MUX_FPGROUP_ZERO 0x10 // Force to be zero.
00028 #define MUX_FPGROUP_PINF 0x20 // "+Inf"
00029 #define MUX_FPGROUP_NINF 0x30 // "-Inf"
00030 #define MUX_FPGROUP_IND 0x40 // "Ind"
00031 #define MUX_FPGROUP_NAN 0x50 // "NaN"
00032 #define MUX_FPGROUP(x) ((x) & 0xF0)
00033
00034
00035
00036 #define MUX_FPCLASS_PINF (MUX_FPGROUP_PINF|0) // Positive infinity (+INF)
00037 #define MUX_FPCLASS_NINF (MUX_FPGROUP_NINF|1) // Negative infinity (-INF)
00038 #define MUX_FPCLASS_QNAN (MUX_FPGROUP_IND |2) // Quiet NAN (Indefinite)
00039 #define MUX_FPCLASS_SNAN (MUX_FPGROUP_NAN |3) // Signaling NAN
00040 #define MUX_FPCLASS_ND (MUX_FPGROUP_ZERO|4) // Negative denormalized
00041 #define MUX_FPCLASS_NZ (MUX_FPGROUP_ZERO|5) // Negative zero (-0)
00042 #define MUX_FPCLASS_PZ (MUX_FPGROUP_ZERO|6) // Positive zero (+0)
00043 #define MUX_FPCLASS_PD (MUX_FPGROUP_ZERO|7) // Positive denormalized
00044 #define MUX_FPCLASS_PN (MUX_FPGROUP_PASS|8) // Positive normalized non-zero
00045 #define MUX_FPCLASS_NN (MUX_FPGROUP_PASS|9) // Negative normalized non-zero
00046 #define MUX_FPCLASS(x) ((x) & 0x0F)
00047
00048 #ifdef WIN32
00049 #define IEEE_MASK_SIGN 0x8000000000000000ui64
00050 #define IEEE_MASK_EXPONENT 0x7FF0000000000000ui64
00051 #define IEEE_MASK_MANTISSA 0x000FFFFFFFFFFFFFui64
00052 #define IEEE_MASK_QNAN 0x0008000000000000ui64
00053 #else
00054 #define IEEE_MASK_SIGN 0x8000000000000000ull
00055 #define IEEE_MASK_EXPONENT 0x7FF0000000000000ull
00056 #define IEEE_MASK_MANTISSA 0x000FFFFFFFFFFFFFull
00057 #define IEEE_MASK_QNAN 0x0008000000000000ull
00058 #endif
00059
00060 #define ARBITRARY_NUMBER 1
00061 #define IEEE_MAKE_TABLESIZE 5
00062 typedef union
00063 {
00064 INT64 i64;
00065 double d;
00066 } SpecialFloatUnion;
00067
00068
00069
00070
00071
00072
00073 static SpecialFloatUnion SpecialFloatTable[IEEE_MAKE_TABLESIZE] =
00074 {
00075 { 0 },
00076 { IEEE_MASK_EXPONENT | IEEE_MASK_QNAN | ARBITRARY_NUMBER },
00077 { IEEE_MASK_EXPONENT | IEEE_MASK_QNAN | ARBITRARY_NUMBER },
00078 { IEEE_MASK_EXPONENT },
00079 { IEEE_MASK_EXPONENT | IEEE_MASK_SIGN }
00080 };
00081
00082 double MakeSpecialFloat(int iWhich)
00083 {
00084 return SpecialFloatTable[iWhich].d;
00085 }
00086
00087 static int mux_fpclass(double result)
00088 {
00089 union
00090 {
00091 UINT64 i64;
00092 double d;
00093 } u;
00094
00095 u.d = result;
00096
00097 if ((u.i64 & IEEE_MASK_EXPONENT) == 0)
00098 {
00099 if (u.i64 & IEEE_MASK_MANTISSA)
00100 {
00101 if (u.i64 & IEEE_MASK_SIGN) return MUX_FPCLASS_ND;
00102 else return MUX_FPCLASS_PD;
00103 }
00104 else
00105 {
00106 if (u.i64 & IEEE_MASK_SIGN) return MUX_FPCLASS_NZ;
00107 else return MUX_FPCLASS_PZ;
00108 }
00109 }
00110 else if ((u.i64 & IEEE_MASK_EXPONENT) == IEEE_MASK_EXPONENT)
00111 {
00112 if (u.i64 & IEEE_MASK_MANTISSA)
00113 {
00114 if (u.i64 & IEEE_MASK_QNAN) return MUX_FPCLASS_QNAN;
00115 else return MUX_FPCLASS_SNAN;
00116 }
00117 else
00118 {
00119 if (u.i64 & IEEE_MASK_SIGN) return MUX_FPCLASS_NINF;
00120 else return MUX_FPCLASS_PINF;
00121 }
00122 }
00123 else
00124 {
00125 if (u.i64 & IEEE_MASK_SIGN) return MUX_FPCLASS_NN;
00126 else return MUX_FPCLASS_PN;
00127 }
00128 }
00129 #endif // HAVE_IEEE_FP_FORMAT
00130
00131 static double AddWithError(double& err, double a, double b)
00132 {
00133 double sum = a+b;
00134 err = b-(sum-a);
00135 return sum;
00136 }
00137
00138
00139
00140
00141 static double NearestPretty(double R)
00142 {
00143 char *rve = NULL;
00144 int decpt;
00145 int bNegative;
00146 const int mode = 0;
00147
00148 double ulpR = ulp(R);
00149 double R0 = R-ulpR;
00150 double R1 = R+ulpR;
00151
00152
00153
00154 char *p = mux_dtoa(R, mode, 50, &decpt, &bNegative, &rve);
00155 int nDigits = rve - p;
00156
00157
00158
00159 p = mux_dtoa(R0, mode, 50, &decpt, &bNegative, &rve);
00160 if (rve - p < nDigits)
00161 {
00162 nDigits = rve - p;
00163 R = R0;
00164 }
00165
00166
00167
00168 p = mux_dtoa(R1, mode, 50, &decpt, &bNegative, &rve);
00169 if (rve - p < nDigits)
00170 {
00171 nDigits = rve - p;
00172 R = R1;
00173 }
00174 return R;
00175 }
00176
00177
00178
00179 static int DCL_CDECL f_comp_abs(const void *s1, const void *s2)
00180 {
00181 double a = fabs(*(double *)s1);
00182 double b = fabs(*(double *)s2);
00183
00184 if (a > b)
00185 {
00186 return -1;
00187 }
00188 else if (a < b)
00189 {
00190 return 1;
00191 }
00192 return 0;
00193 }
00194
00195
00196
00197
00198
00199
00200 static double AddDoubles(int n, double pd[])
00201 {
00202 qsort(pd, n, sizeof(double), f_comp_abs);
00203 double sum = 0.0;
00204 if (0 < n)
00205 {
00206 sum = pd[0];
00207 double sum_err = 0.0;
00208 int i;
00209 for (i = 1; i < n; i++)
00210 {
00211 double addend_err;
00212 double addend = AddWithError(addend_err, sum_err, pd[i]);
00213 double sum1_err;
00214 double sum1 = AddWithError(sum1_err, sum, addend);
00215 sum = AddWithError(sum_err, sum1, addend_err + sum1_err);
00216 }
00217 }
00218 return NearestPretty(sum);
00219 }
00220
00221
00222
00223
00224 static void fval(char *buff, char **bufc, double result)
00225 {
00226
00227
00228 #ifdef HAVE_IEEE_FP_FORMAT
00229 int fpc = mux_fpclass(result);
00230 if (MUX_FPGROUP(fpc) == MUX_FPGROUP_PASS)
00231 {
00232 #endif // HAVE_IEEE_FP_FORMAT
00233 double rIntegerPart;
00234 double rFractionalPart = modf(result, &rIntegerPart);
00235 if ( 0.0 == rFractionalPart
00236 && LONG_MIN <= rIntegerPart
00237 && rIntegerPart <= LONG_MAX)
00238 {
00239 long i = (long)rIntegerPart;
00240 safe_ltoa(i, buff, bufc);
00241 }
00242 else
00243 {
00244 safe_str(mux_ftoa(result, false, 0), buff, bufc);
00245 }
00246 #ifdef HAVE_IEEE_FP_FORMAT
00247 }
00248 else
00249 {
00250 safe_str(mux_FPStrings[MUX_FPCLASS(fpc)], buff, bufc);
00251 }
00252 #endif // HAVE_IEEE_FP_FORMAT
00253 }
00254
00255 static const long nMaximums[10] =
00256 {
00257 0, 9, 99, 999, 9999, 99999, 999999, 9999999, 99999999, 999999999
00258 };
00259
00260 static double g_aDoubles[LBUF_SIZE];
00261 int const g_nDoubles = sizeof(g_aDoubles)/sizeof(double);
00262
00263 FUNCTION(fun_add)
00264 {
00265 UNUSED_PARAMETER(executor);
00266 UNUSED_PARAMETER(caller);
00267 UNUSED_PARAMETER(enactor);
00268 UNUSED_PARAMETER(cargs);
00269 UNUSED_PARAMETER(ncargs);
00270
00271 int nArgs = nfargs;
00272 if (g_nDoubles < nArgs)
00273 {
00274 nArgs = g_nDoubles;
00275 }
00276
00277 int i;
00278 for (i = 0; i < nArgs; i++)
00279 {
00280 int nDigits;
00281 long nMaxValue = 0;
00282 if ( !is_integer(fargs[i], &nDigits)
00283 || nDigits > 9
00284 || (nMaxValue += nMaximums[nDigits]) > 999999999L)
00285 {
00286
00287
00288 for (int j = 0; j < nArgs; j++)
00289 {
00290 g_aDoubles[j] = mux_atof(fargs[j]);
00291 }
00292
00293 fval(buff, bufc, AddDoubles(nArgs, g_aDoubles));
00294 return;
00295 }
00296 }
00297
00298
00299
00300 long sum = 0;
00301 for (i = 0; i < nArgs; i++)
00302 {
00303 sum += mux_atol(fargs[i]);
00304 }
00305 safe_ltoa(sum, buff, bufc);
00306 }
00307
00308 FUNCTION(fun_ladd)
00309 {
00310 UNUSED_PARAMETER(executor);
00311 UNUSED_PARAMETER(caller);
00312 UNUSED_PARAMETER(enactor);
00313 UNUSED_PARAMETER(cargs);
00314 UNUSED_PARAMETER(ncargs);
00315
00316 int n = 0;
00317 if (0 < nfargs)
00318 {
00319 SEP sep;
00320 if (!OPTIONAL_DELIM(2, sep, DELIM_DFLT|DELIM_STRING))
00321 {
00322 return;
00323 }
00324
00325 char *cp = trim_space_sep(fargs[0], &sep);
00326 while ( cp
00327 && n < g_nDoubles)
00328 {
00329 char *curr = split_token(&cp, &sep);
00330 g_aDoubles[n++] = mux_atof(curr);
00331 }
00332 }
00333 fval(buff, bufc, AddDoubles(n, g_aDoubles));
00334 }
00335
00337
00338
00339
00341
00342 FUNCTION(fun_iadd)
00343 {
00344 UNUSED_PARAMETER(executor);
00345 UNUSED_PARAMETER(caller);
00346 UNUSED_PARAMETER(enactor);
00347 UNUSED_PARAMETER(cargs);
00348 UNUSED_PARAMETER(ncargs);
00349
00350 INT64 sum = 0;
00351 for (int i = 0; i < nfargs; i++)
00352 {
00353 sum += mux_atoi64(fargs[i]);
00354 }
00355 safe_i64toa(sum, buff, bufc);
00356 }
00357
00358 FUNCTION(fun_sub)
00359 {
00360 UNUSED_PARAMETER(executor);
00361 UNUSED_PARAMETER(caller);
00362 UNUSED_PARAMETER(enactor);
00363 UNUSED_PARAMETER(nfargs);
00364 UNUSED_PARAMETER(cargs);
00365 UNUSED_PARAMETER(ncargs);
00366
00367 int nDigits;
00368 if ( is_integer(fargs[0], &nDigits)
00369 && nDigits <= 9
00370 && is_integer(fargs[1], &nDigits)
00371 && nDigits <= 9)
00372 {
00373 int iResult;
00374 iResult = mux_atol(fargs[0]) - mux_atol(fargs[1]);
00375 safe_ltoa(iResult, buff, bufc);
00376 }
00377 else
00378 {
00379 g_aDoubles[0] = mux_atof(fargs[0]);
00380 g_aDoubles[1] = -mux_atof(fargs[1]);
00381 fval(buff, bufc, AddDoubles(2, g_aDoubles));
00382 }
00383 }
00384
00386
00387
00388
00390
00391 FUNCTION(fun_isub)
00392 {
00393 UNUSED_PARAMETER(executor);
00394 UNUSED_PARAMETER(caller);
00395 UNUSED_PARAMETER(enactor);
00396 UNUSED_PARAMETER(nfargs);
00397 UNUSED_PARAMETER(cargs);
00398 UNUSED_PARAMETER(ncargs);
00399
00400 INT64 diff = mux_atoi64(fargs[0]) - mux_atoi64(fargs[1]);
00401 safe_i64toa(diff, buff, bufc);
00402 }
00403
00404 FUNCTION(fun_mul)
00405 {
00406 UNUSED_PARAMETER(executor);
00407 UNUSED_PARAMETER(caller);
00408 UNUSED_PARAMETER(enactor);
00409 UNUSED_PARAMETER(cargs);
00410 UNUSED_PARAMETER(ncargs);
00411
00412 double prod = 1.0;
00413 for (int i = 0; i < nfargs; i++)
00414 {
00415 prod *= mux_atof(fargs[i]);
00416 }
00417 fval(buff, bufc, NearestPretty(prod));
00418 }
00419
00421
00422
00423
00425
00426 FUNCTION(fun_imul)
00427 {
00428 UNUSED_PARAMETER(executor);
00429 UNUSED_PARAMETER(caller);
00430 UNUSED_PARAMETER(enactor);
00431 UNUSED_PARAMETER(cargs);
00432 UNUSED_PARAMETER(ncargs);
00433
00434 INT64 prod = 1;
00435 for (int i = 0; i < nfargs; i++)
00436 {
00437 prod *= mux_atoi64(fargs[i]);
00438 }
00439 safe_i64toa(prod, buff, bufc);
00440 }
00441
00442 FUNCTION(fun_gt)
00443 {
00444 UNUSED_PARAMETER(executor);
00445 UNUSED_PARAMETER(caller);
00446 UNUSED_PARAMETER(enactor);
00447 UNUSED_PARAMETER(nfargs);
00448 UNUSED_PARAMETER(cargs);
00449 UNUSED_PARAMETER(ncargs);
00450
00451 bool bResult = false;
00452 int nDigits;
00453 if ( is_integer(fargs[0], &nDigits)
00454 && nDigits <= 9
00455 && is_integer(fargs[1], &nDigits)
00456 && nDigits <= 9)
00457 {
00458 bResult = (mux_atol(fargs[0]) > mux_atol(fargs[1]));
00459 }
00460 else
00461 {
00462 bResult = (mux_atof(fargs[0]) > mux_atof(fargs[1]));
00463 }
00464 safe_bool(bResult, buff, bufc);
00465 }
00466
00467 FUNCTION(fun_gte)
00468 {
00469 UNUSED_PARAMETER(executor);
00470 UNUSED_PARAMETER(caller);
00471 UNUSED_PARAMETER(enactor);
00472 UNUSED_PARAMETER(nfargs);
00473 UNUSED_PARAMETER(cargs);
00474 UNUSED_PARAMETER(ncargs);
00475
00476 bool bResult = false;
00477 int nDigits;
00478 if ( is_integer(fargs[0], &nDigits)
00479 && nDigits <= 9
00480 && is_integer(fargs[1], &nDigits)
00481 && nDigits <= 9)
00482 {
00483 bResult = (mux_atol(fargs[0]) >= mux_atol(fargs[1]));
00484 }
00485 else
00486 {
00487 bResult = (mux_atof(fargs[0]) >= mux_atof(fargs[1]));
00488 }
00489 safe_bool(bResult, buff, bufc);
00490 }
00491
00492 FUNCTION(fun_lt)
00493 {
00494 UNUSED_PARAMETER(executor);
00495 UNUSED_PARAMETER(caller);
00496 UNUSED_PARAMETER(enactor);
00497 UNUSED_PARAMETER(nfargs);
00498 UNUSED_PARAMETER(cargs);
00499 UNUSED_PARAMETER(ncargs);
00500
00501 bool bResult = false;
00502 int nDigits;
00503 if ( is_integer(fargs[0], &nDigits)
00504 && nDigits <= 9
00505 && is_integer(fargs[1], &nDigits)
00506 && nDigits <= 9)
00507 {
00508 bResult = (mux_atol(fargs[0]) < mux_atol(fargs[1]));
00509 }
00510 else
00511 {
00512 bResult = (mux_atof(fargs[0]) < mux_atof(fargs[1]));
00513 }
00514 safe_bool(bResult, buff, bufc);
00515 }
00516
00517 FUNCTION(fun_lte)
00518 {
00519 UNUSED_PARAMETER(executor);
00520 UNUSED_PARAMETER(caller);
00521 UNUSED_PARAMETER(enactor);
00522 UNUSED_PARAMETER(nfargs);
00523 UNUSED_PARAMETER(cargs);
00524 UNUSED_PARAMETER(ncargs);
00525
00526 bool bResult = false;
00527 int nDigits;
00528 if ( is_integer(fargs[0], &nDigits)
00529 && nDigits <= 9
00530 && is_integer(fargs[1], &nDigits)
00531 && nDigits <= 9)
00532 {
00533 bResult = (mux_atol(fargs[0]) <= mux_atol(fargs[1]));
00534 }
00535 else
00536 {
00537 bResult = (mux_atof(fargs[0]) <= mux_atof(fargs[1]));
00538 }
00539 safe_bool(bResult, buff, bufc);
00540 }
00541
00542 FUNCTION(fun_eq)
00543 {
00544 UNUSED_PARAMETER(executor);
00545 UNUSED_PARAMETER(caller);
00546 UNUSED_PARAMETER(enactor);
00547 UNUSED_PARAMETER(nfargs);
00548 UNUSED_PARAMETER(cargs);
00549 UNUSED_PARAMETER(ncargs);
00550
00551 bool bResult = false;
00552 int nDigits;
00553 if ( is_integer(fargs[0], &nDigits)
00554 && nDigits <= 9
00555 && is_integer(fargs[1], &nDigits)
00556 && nDigits <= 9)
00557 {
00558 bResult = (mux_atol(fargs[0]) == mux_atol(fargs[1]));
00559 }
00560 else
00561 {
00562 bResult = ( strcmp(fargs[0], fargs[1]) == 0
00563 || mux_atof(fargs[0]) == mux_atof(fargs[1]));
00564 }
00565 safe_bool(bResult, buff, bufc);
00566 }
00567
00568 FUNCTION(fun_neq)
00569 {
00570 UNUSED_PARAMETER(executor);
00571 UNUSED_PARAMETER(caller);
00572 UNUSED_PARAMETER(enactor);
00573 UNUSED_PARAMETER(nfargs);
00574 UNUSED_PARAMETER(cargs);
00575 UNUSED_PARAMETER(ncargs);
00576
00577 bool bResult = false;
00578 int nDigits;
00579 if ( is_integer(fargs[0], &nDigits)
00580 && nDigits <= 9
00581 && is_integer(fargs[1], &nDigits)
00582 && nDigits <= 9)
00583 {
00584 bResult = (mux_atol(fargs[0]) != mux_atol(fargs[1]));
00585 }
00586 else
00587 {
00588 bResult = ( strcmp(fargs[0], fargs[1]) != 0
00589 && mux_atof(fargs[0]) != mux_atof(fargs[1]));
00590 }
00591 safe_bool(bResult, buff, bufc);
00592 }
00593
00594
00595
00596
00597
00598
00599 FUNCTION(fun_max)
00600 {
00601 UNUSED_PARAMETER(executor);
00602 UNUSED_PARAMETER(caller);
00603 UNUSED_PARAMETER(enactor);
00604 UNUSED_PARAMETER(cargs);
00605 UNUSED_PARAMETER(ncargs);
00606
00607 double maximum = 0.0;
00608 for (int i = 0; i < nfargs; i++)
00609 {
00610 double tval = mux_atof(fargs[i]);
00611 if ( i == 0
00612 || tval > maximum)
00613 {
00614 maximum = tval;
00615 }
00616 }
00617 fval(buff, bufc, maximum);
00618 }
00619
00620 FUNCTION(fun_min)
00621 {
00622 UNUSED_PARAMETER(executor);
00623 UNUSED_PARAMETER(caller);
00624 UNUSED_PARAMETER(enactor);
00625 UNUSED_PARAMETER(cargs);
00626 UNUSED_PARAMETER(ncargs);
00627
00628 double minimum = 0.0;
00629 for (int i = 0; i < nfargs; i++)
00630 {
00631 double tval = mux_atof(fargs[i]);
00632 if ( i == 0
00633 || tval < minimum)
00634 {
00635 minimum = tval;
00636 }
00637 }
00638 fval(buff, bufc, minimum);
00639 }
00640
00641
00642
00643
00644
00645 FUNCTION(fun_sign)
00646 {
00647 UNUSED_PARAMETER(executor);
00648 UNUSED_PARAMETER(caller);
00649 UNUSED_PARAMETER(enactor);
00650 UNUSED_PARAMETER(nfargs);
00651 UNUSED_PARAMETER(cargs);
00652 UNUSED_PARAMETER(ncargs);
00653
00654 double num = mux_atof(fargs[0]);
00655 if (num < 0)
00656 {
00657 safe_str("-1", buff, bufc);
00658 }
00659 else
00660 {
00661 safe_bool(num > 0, buff, bufc);
00662 }
00663 }
00664
00665
00666
00667 FUNCTION(fun_isign)
00668 {
00669 UNUSED_PARAMETER(executor);
00670 UNUSED_PARAMETER(caller);
00671 UNUSED_PARAMETER(enactor);
00672 UNUSED_PARAMETER(nfargs);
00673 UNUSED_PARAMETER(cargs);
00674 UNUSED_PARAMETER(ncargs);
00675
00676 INT64 num = mux_atoi64(fargs[0]);
00677
00678 if (num < 0)
00679 {
00680 safe_str("-1", buff, bufc);
00681 }
00682 else
00683 {
00684 safe_bool(num > 0, buff, bufc);
00685 }
00686 }
00687
00688
00689
00690 FUNCTION(fun_shl)
00691 {
00692 UNUSED_PARAMETER(executor);
00693 UNUSED_PARAMETER(caller);
00694 UNUSED_PARAMETER(enactor);
00695 UNUSED_PARAMETER(nfargs);
00696 UNUSED_PARAMETER(cargs);
00697 UNUSED_PARAMETER(ncargs);
00698
00699 if ( is_integer(fargs[0], NULL)
00700 && is_integer(fargs[1], NULL))
00701 {
00702 INT64 a = mux_atoi64(fargs[0]);
00703 long b = mux_atol(fargs[1]);
00704 safe_i64toa(a << b, buff, bufc);
00705 }
00706 else
00707 {
00708 safe_str("#-1 ARGUMENTS MUST BE INTEGERS", buff, bufc);
00709 }
00710 }
00711
00712 FUNCTION(fun_shr)
00713 {
00714 UNUSED_PARAMETER(executor);
00715 UNUSED_PARAMETER(caller);
00716 UNUSED_PARAMETER(enactor);
00717 UNUSED_PARAMETER(nfargs);
00718 UNUSED_PARAMETER(cargs);
00719 UNUSED_PARAMETER(ncargs);
00720
00721 if ( is_integer(fargs[0], NULL)
00722 && is_integer(fargs[1], NULL))
00723 {
00724 INT64 a = mux_atoi64(fargs[0]);
00725 long b = mux_atol(fargs[1]);
00726 safe_i64toa(a >> b, buff, bufc);
00727 }
00728 else
00729 {
00730 safe_str("#-1 ARGUMENTS MUST BE INTEGERS", buff, bufc);
00731 }
00732 }
00733
00734 FUNCTION(fun_inc)
00735 {
00736 UNUSED_PARAMETER(executor);
00737 UNUSED_PARAMETER(caller);
00738 UNUSED_PARAMETER(enactor);
00739 UNUSED_PARAMETER(cargs);
00740 UNUSED_PARAMETER(ncargs);
00741
00742 if (nfargs == 1)
00743 {
00744 safe_i64toa(mux_atoi64(fargs[0]) + 1, buff, bufc);
00745 }
00746 else
00747 {
00748 safe_chr('1', buff, bufc);
00749 }
00750 }
00751
00752 FUNCTION(fun_dec)
00753 {
00754 UNUSED_PARAMETER(executor);
00755 UNUSED_PARAMETER(caller);
00756 UNUSED_PARAMETER(enactor);
00757 UNUSED_PARAMETER(cargs);
00758 UNUSED_PARAMETER(ncargs);
00759
00760 if (nfargs == 1)
00761 {
00762 safe_i64toa(mux_atoi64(fargs[0]) - 1, buff, bufc);
00763 }
00764 else
00765 {
00766 safe_str("-1", buff, bufc);
00767 }
00768 }
00769
00770 FUNCTION(fun_trunc)
00771 {
00772 UNUSED_PARAMETER(executor);
00773 UNUSED_PARAMETER(caller);
00774 UNUSED_PARAMETER(enactor);
00775 UNUSED_PARAMETER(nfargs);
00776 UNUSED_PARAMETER(cargs);
00777 UNUSED_PARAMETER(ncargs);
00778
00779 double rArg = mux_atof(fargs[0]);
00780 double rIntegerPart;
00781
00782 mux_FPRestore();
00783 (void)modf(rArg, &rIntegerPart);
00784 mux_FPSet();
00785
00786 #ifdef HAVE_IEEE_FP_FORMAT
00787 int fpc = mux_fpclass(rIntegerPart);
00788 if (MUX_FPGROUP(fpc) == MUX_FPGROUP_PASS)
00789 {
00790 #endif // HAVE_IEEE_FP_FORMAT
00791 safe_tprintf_str(buff, bufc, "%.0f", rIntegerPart);
00792 #ifdef HAVE_IEEE_FP_FORMAT
00793 }
00794 else
00795 {
00796 safe_str(mux_FPStrings[MUX_FPCLASS(fpc)], buff, bufc);
00797 }
00798 #endif // HAVE_IEEE_FP_FORMAT
00799 }
00800
00801 FUNCTION(fun_fdiv)
00802 {
00803 UNUSED_PARAMETER(executor);
00804 UNUSED_PARAMETER(caller);
00805 UNUSED_PARAMETER(enactor);
00806 UNUSED_PARAMETER(nfargs);
00807 UNUSED_PARAMETER(cargs);
00808 UNUSED_PARAMETER(ncargs);
00809
00810 double bot = mux_atof(fargs[1]);
00811 double top = mux_atof(fargs[0]);
00812 #ifndef HAVE_IEEE_FP_SNAN
00813 if (bot == 0.0)
00814 {
00815 if (top > 0.0)
00816 {
00817 safe_str("+Inf", buff, bufc);
00818 }
00819 else if (top < 0.0)
00820 {
00821 safe_str("-Inf", buff, bufc);
00822 }
00823 else
00824 {
00825 safe_str("Ind", buff, bufc);
00826 }
00827 }
00828 else
00829 {
00830 fval(buff, bufc, top/bot);
00831 }
00832 #else
00833 fval(buff, bufc, top/bot);
00834 #endif
00835 }
00836
00837 FUNCTION(fun_idiv)
00838 {
00839 UNUSED_PARAMETER(executor);
00840 UNUSED_PARAMETER(caller);
00841 UNUSED_PARAMETER(enactor);
00842 UNUSED_PARAMETER(nfargs);
00843 UNUSED_PARAMETER(cargs);
00844 UNUSED_PARAMETER(ncargs);
00845
00846 INT64 bot, top;
00847
00848 bot = mux_atoi64(fargs[1]);
00849 if (bot == 0)
00850 {
00851 safe_str("#-1 DIVIDE BY ZERO", buff, bufc);
00852 }
00853 else
00854 {
00855 top = mux_atoi64(fargs[0]);
00856 top = i64Division(top, bot);
00857 safe_i64toa(top, buff, bufc);
00858 }
00859 }
00860
00861 FUNCTION(fun_floordiv)
00862 {
00863 UNUSED_PARAMETER(executor);
00864 UNUSED_PARAMETER(caller);
00865 UNUSED_PARAMETER(enactor);
00866 UNUSED_PARAMETER(nfargs);
00867 UNUSED_PARAMETER(cargs);
00868 UNUSED_PARAMETER(ncargs);
00869
00870 INT64 bot, top;
00871
00872 bot = mux_atoi64(fargs[1]);
00873 if (bot == 0)
00874 {
00875 safe_str("#-1 DIVIDE BY ZERO", buff, bufc);
00876 }
00877 else
00878 {
00879 top = mux_atoi64(fargs[0]);
00880 top = i64FloorDivision(top, bot);
00881 safe_i64toa(top, buff, bufc);
00882 }
00883 }
00884
00885 FUNCTION(fun_mod)
00886 {
00887 UNUSED_PARAMETER(executor);
00888 UNUSED_PARAMETER(caller);
00889 UNUSED_PARAMETER(enactor);
00890 UNUSED_PARAMETER(nfargs);
00891 UNUSED_PARAMETER(cargs);
00892 UNUSED_PARAMETER(ncargs);
00893
00894 INT64 bot, top;
00895
00896 bot = mux_atoi64(fargs[1]);
00897 if (bot == 0)
00898 {
00899 bot = 1;
00900 }
00901 top = mux_atoi64(fargs[0]);
00902 top = i64Mod(top, bot);
00903 safe_i64toa(top, buff, bufc);
00904 }
00905
00906 FUNCTION(fun_remainder)
00907 {
00908 UNUSED_PARAMETER(executor);
00909 UNUSED_PARAMETER(caller);
00910 UNUSED_PARAMETER(enactor);
00911 UNUSED_PARAMETER(nfargs);
00912 UNUSED_PARAMETER(cargs);
00913 UNUSED_PARAMETER(ncargs);
00914
00915 INT64 bot, top;
00916
00917 bot = mux_atoi64(fargs[1]);
00918 if (bot == 0)
00919 {
00920 bot = 1;
00921 }
00922 top = mux_atoi64(fargs[0]);
00923 top = i64Remainder(top, bot);
00924 safe_i64toa(top, buff, bufc);
00925 }
00926
00927
00928
00929
00930
00931 FUNCTION(fun_abs)
00932 {
00933 UNUSED_PARAMETER(executor);
00934 UNUSED_PARAMETER(caller);
00935 UNUSED_PARAMETER(enactor);
00936 UNUSED_PARAMETER(nfargs);
00937 UNUSED_PARAMETER(cargs);
00938 UNUSED_PARAMETER(ncargs);
00939
00940 double num = mux_atof(fargs[0]);
00941 if (num == 0.0)
00942 {
00943 safe_chr('0', buff, bufc);
00944 }
00945 else if (num < 0.0)
00946 {
00947 fval(buff, bufc, -num);
00948 }
00949 else
00950 {
00951 fval(buff, bufc, num);
00952 }
00953 }
00954
00955
00956
00957 FUNCTION(fun_iabs)
00958 {
00959 UNUSED_PARAMETER(executor);
00960 UNUSED_PARAMETER(caller);
00961 UNUSED_PARAMETER(enactor);
00962 UNUSED_PARAMETER(nfargs);
00963 UNUSED_PARAMETER(cargs);
00964 UNUSED_PARAMETER(ncargs);
00965
00966 INT64 num = mux_atoi64(fargs[0]);
00967
00968 if (num == 0)
00969 {
00970 safe_chr('0', buff, bufc);
00971 }
00972 else if (num < 0)
00973 {
00974 safe_i64toa(-num, buff, bufc);
00975 }
00976 else
00977 {
00978 safe_i64toa(num, buff, bufc);
00979 }
00980 }
00981
00982 FUNCTION(fun_dist2d)
00983 {
00984 UNUSED_PARAMETER(executor);
00985 UNUSED_PARAMETER(caller);
00986 UNUSED_PARAMETER(enactor);
00987 UNUSED_PARAMETER(nfargs);
00988 UNUSED_PARAMETER(cargs);
00989 UNUSED_PARAMETER(ncargs);
00990
00991 double d;
00992 double sum;
00993
00994 d = mux_atof(fargs[0]) - mux_atof(fargs[2]);
00995 sum = d * d;
00996 d = mux_atof(fargs[1]) - mux_atof(fargs[3]);
00997 sum += d * d;
00998
00999 mux_FPRestore();
01000 double result = sqrt(sum);
01001 mux_FPSet();
01002
01003 fval(buff, bufc, result);
01004 }
01005
01006 FUNCTION(fun_dist3d)
01007 {
01008 UNUSED_PARAMETER(executor);
01009 UNUSED_PARAMETER(caller);
01010 UNUSED_PARAMETER(enactor);
01011 UNUSED_PARAMETER(nfargs);
01012 UNUSED_PARAMETER(cargs);
01013 UNUSED_PARAMETER(ncargs);
01014
01015 double d;
01016 double sum;
01017
01018 d = mux_atof(fargs[0]) - mux_atof(fargs[3]);
01019 sum = d * d;
01020 d = mux_atof(fargs[1]) - mux_atof(fargs[4]);
01021 sum += d * d;
01022 d = mux_atof(fargs[2]) - mux_atof(fargs[5]);
01023 sum += d * d;
01024
01025 mux_FPRestore();
01026 double result = sqrt(sum);
01027 mux_FPSet();
01028
01029 fval(buff, bufc, result);
01030 }
01031
01032
01033
01034
01035
01036 #define VADD_F 0
01037 #define VSUB_F 1
01038 #define VMUL_F 2
01039 #define VDOT_F 3
01040 #define VCROSS_F 4
01041
01042 static void handle_vectors
01043 (
01044 char *vecarg1, char *vecarg2, char *buff, char **bufc, SEP *psep,
01045 SEP *posep, int flag
01046 )
01047 {
01048 char *v1[(LBUF_SIZE+1)/2], *v2[(LBUF_SIZE+1)/2];
01049 double scalar;
01050 int n, m, i;
01051
01052
01053
01054 if (!vecarg1 || !*vecarg1 || !vecarg2 || !*vecarg2)
01055 {
01056 return;
01057 }
01058 n = list2arr(v1, (LBUF_SIZE+1)/2, vecarg1, psep);
01059 m = list2arr(v2, (LBUF_SIZE+1)/2, vecarg2, psep);
01060
01061
01062
01063
01064 if ( n != m
01065 && !( ( flag == VMUL_F
01066 || flag == VADD_F
01067 || flag == VSUB_F)
01068 && ( n == 1
01069 || m == 1)))
01070 {
01071 safe_str("#-1 VECTORS MUST BE SAME DIMENSIONS", buff, bufc);
01072 return;
01073 }
01074
01075 switch (flag)
01076 {
01077 case VADD_F:
01078
01079
01080
01081
01082 if (n == 1)
01083 {
01084 scalar = mux_atof(v1[0]);
01085 for (i = 0; i < m; i++)
01086 {
01087 if (i != 0)
01088 {
01089 print_sep(posep, buff, bufc);
01090 }
01091 fval(buff, bufc, mux_atof(v2[i]) + scalar);
01092 }
01093 n = m;
01094 }
01095 else if (m == 1)
01096 {
01097 scalar = mux_atof(v2[0]);
01098 for (i = 0; i < n; i++)
01099 {
01100 if (i != 0)
01101 {
01102 print_sep(posep, buff, bufc);
01103 }
01104 fval(buff, bufc, mux_atof(v1[i]) + scalar);
01105 }
01106 }
01107 else
01108 {
01109 for (i = 0; i < n; i++)
01110 {
01111 if (i != 0)
01112 {
01113 print_sep(posep, buff, bufc);
01114 }
01115 double a = mux_atof(v1[i]);
01116 double b = mux_atof(v2[i]);
01117 fval(buff, bufc, a + b);
01118 }
01119 }
01120 break;
01121
01122 case VSUB_F:
01123
01124 if (n == 1)
01125 {
01126
01127
01128 scalar = mux_atof(v1[0]);
01129 for (i = 0; i < m; i++)
01130 {
01131 if (i != 0)
01132 {
01133 print_sep(posep, buff, bufc);
01134 }
01135 fval(buff, bufc, scalar - mux_atof(v2[i]));
01136 }
01137 }
01138 else if (m == 1)
01139 {
01140
01141
01142 scalar = mux_atof(v2[0]);
01143 for (i = 0; i < n; i++)
01144 {
01145 if (i != 0)
01146 {
01147 print_sep(posep, buff, bufc);
01148 }
01149 fval(buff, bufc, mux_atof(v1[i]) - scalar);
01150 }
01151 }
01152 else
01153 {
01154
01155
01156 for (i = 0; i < n; i++)
01157 {
01158 if (i != 0)
01159 {
01160 print_sep(posep, buff, bufc);
01161 }
01162 double a = mux_atof(v1[i]);
01163 double b = mux_atof(v2[i]);
01164 fval(buff, bufc, a - b);
01165 }
01166 }
01167 break;
01168
01169 case VMUL_F:
01170
01171
01172
01173
01174 if (n == 1)
01175 {
01176 scalar = mux_atof(v1[0]);
01177 for (i = 0; i < m; i++)
01178 {
01179 if (i != 0)
01180 {
01181 print_sep(posep, buff, bufc);
01182 }
01183 fval(buff, bufc, mux_atof(v2[i]) * scalar);
01184 }
01185 }
01186 else if (m == 1)
01187 {
01188 scalar = mux_atof(v2[0]);
01189 for (i = 0; i < n; i++)
01190 {
01191 if (i != 0)
01192 {
01193 print_sep(posep, buff, bufc);
01194 }
01195 fval(buff, bufc, mux_atof(v1[i]) * scalar);
01196 }
01197 }
01198 else
01199 {
01200
01201
01202 for (i = 0; i < n; i++)
01203 {
01204 if (i != 0)
01205 {
01206 print_sep(posep, buff, bufc);
01207 }
01208 double a = mux_atof(v1[i]);
01209 double b = mux_atof(v2[i]);
01210 fval(buff, bufc, a * b);
01211 }
01212 }
01213 break;
01214
01215 case VDOT_F:
01216
01217 scalar = 0.0;
01218 for (i = 0; i < n; i++)
01219 {
01220 double a = mux_atof(v1[i]);
01221 double b = mux_atof(v2[i]);
01222 scalar += a * b;
01223 }
01224 fval(buff, bufc, scalar);
01225 break;
01226
01227 case VCROSS_F:
01228
01229
01230
01231
01232
01233
01234
01235
01236
01237
01238
01239
01240
01241 if (n != 3)
01242 {
01243 safe_str("#-1 VECTORS MUST BE DIMENSION OF 3", buff, bufc);
01244 }
01245 else
01246 {
01247 double a[2][3];
01248 for (i = 0; i < 3; i++)
01249 {
01250 a[0][i] = mux_atof(v1[i]);
01251 a[1][i] = mux_atof(v2[i]);
01252 }
01253 fval(buff, bufc, (a[0][1] * a[1][2]) - (a[0][2] * a[1][1]));
01254 print_sep(posep, buff, bufc);
01255 fval(buff, bufc, (a[0][2] * a[1][0]) - (a[0][0] * a[1][2]));
01256 print_sep(posep, buff, bufc);
01257 fval(buff, bufc, (a[0][0] * a[1][1]) - (a[0][1] * a[1][0]));
01258 }
01259 break;
01260
01261 default:
01262
01263
01264
01265 safe_str("#-1 UNIMPLEMENTED", buff, bufc);
01266 }
01267 }
01268
01269 FUNCTION(fun_vadd)
01270 {
01271 SEP sep;
01272 if (!