libsrc/tumble.cxx

Go to the documentation of this file.
00001 /**********************************************************************
00002  * Copyright 2002 Jeff Rush <jrush@taupro.com>
00003  * Original Copyright 1979-2002 Udanax.com
00004  *
00005  * This file is part of the Udanax xanalogical storage system.
00006  *
00007  * Udanax is free software; you can redistribute it and/or modify it
00008  * under the terms of the GNU General Public License as published by
00009  * the Free Software Foundation; either version 2 of the License, or
00010  * (at your option) any later version.
00011  *
00012  * Udanax is distributed in the hope that it will be useful, but
00013  * WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with Udanax; if not, write to the Free Software Foundation,
00019  * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020  **********************************************************************/
00021 
00030 /* Modification History:
00031  * $Log: tumble.cxx,v $
00032  * Revision 1.12  2004/09/11 13:59:21  jrush
00033  * Changed all fprintf's to stderr to use the Nana library L() macro.  Also
00034  * removed a 2-3 minor compiler warnings.
00035  *
00036  * Revision 1.11  2004/09/04 16:02:18  jrush
00037  * Added Doxygen headers before each and every function definition.
00038  *
00039  * Revision 1.10  2002/07/14 08:35:24  jrush
00040  * Replace gerror(), qerror() with assert()
00041  *
00042  * Revision 1.9  2002/05/28 04:22:29  jrush
00043  * Adjusted source files to comply with GPL licensing.
00044  *
00045  * Revision 1.8  2002/05/28 02:52:23  jrush
00046  * Made static any functions and global variables private to this source file
00047  * and commented out any unused functions.
00048  *
00049  * Revision 1.7  2002/04/12 22:53:20  jrush
00050  * Changed from using my setmem() to the clib's memset() and removed no
00051  * longer-needed usefull.cxx
00052  *
00053  * Revision 1.6  2002/04/12 11:56:43  jrush
00054  * Reorganized include file layout, renamed xanadu.h to udanax.h and
00055  * typecontext/typecrumcontext to C++ class Context/CrumContext.
00056  *
00057  * Revision 1.5  2002/04/09 21:45:46  jrush
00058  * Renamed class 'tumbler' to 'Tumbler', for consistency with Python sources,
00059  * and changed typeisa from typedef to a subclass, in preparation for cleaning
00060  * up the type/class tree.
00061  *
00062  * Revision 1.4  2002/04/06 19:51:30  jrush
00063  * Renamed TRUE/FALSE constant use to the C++ standard of true/false.
00064  *
00065  * Revision 1.3  2002/04/06 15:01:17  jrush
00066  * Changed INT to just 'int'.
00067  *
00068  * Revision 1.2  2002/02/14 09:27:43  jrush
00069  * Cleaned up source:
00070  *
00071  * 1. ran thru the indent tool to achieve a standard look,
00072  * 2. added structured comments at top for use with DOxygen reporting
00073  *    as well as CVS keywords,
00074  * 3. fixed compiler warnings re ambiguous assign/compares,
00075  *    needed casts and unused/uninitialized variables,
00076  * 4. fixed funcs that didn't specify a return type,
00077  * 5. centralized prototypes in protos.h, removing incomplete ones,
00078  * 6. cleaned up use of bool/BOOLEAN type to suit C++ type,
00079  * 7. fixed initializer nesting in tumbler constants,
00080  * 8. renamed vars that conflict with C++ keywords (new, this),
00081  * 9. fixed global/extern confusion re some global vars.
00082  *
00083  */
00084 
00085 #include "udanax.h"
00086 
00087 Tumbler ZEROTUMBLERvar;
00088 
00089 static int abscmp(Tumbler *aptr, Tumbler *bptr);
00090 
00091 /* ---------------- Routines to test tumblers -------------- */
00092 
00100     bool
00101 tumblereq(
00102     Tumbler *a,
00103     Tumbler *b)
00104 {
00105     char *aptr = (char *)a;    /* char * for cheating in compare loop */
00106     char *bptr = (char *)b;
00107     int i;
00108 
00109 /* return (tumblercmp (aptr, bptr) == EQUAL);// old safe & slow// */
00110 /* could speed up by doing comparison directly or stealing from abscmp */
00111     i = (int)aptr + sizeof(Tumbler);
00112     for (; ((int)aptr) < i;) {
00113         if (*aptr++ != *bptr++)
00114             return false;
00115     }
00116     return true;
00117 }
00118 
00126     bool
00127 tumbleraccounteq(
00128     Tumbler *aptr,
00129     Tumbler *bptr)
00130 {
00131     int i, j;
00132 
00133     if (aptr->exp != bptr->exp || aptr->sign != bptr->sign)
00134         return false;
00135 
00136     for (j = 0, i = 0; i < NPLACES; i++) {
00137         if (aptr->mantissa[i] != bptr->mantissa[i])
00138             return false;
00139 
00140         if (aptr->mantissa[i] == 0 && ++j == 2)
00141             return true;
00142     }
00143     return true;
00144 }
00145 
00153     int
00154 tumblercmp(
00155     Tumbler *aptr,
00156     Tumbler *bptr)
00157 {
00158     if (iszerotumbler(aptr)) {
00159         if (iszerotumbler(bptr))
00160             return EQUAL;
00161         else
00162             return (bptr->sign ? GREATER : LESS);
00163     }
00164 
00165     if (iszerotumbler(bptr))
00166         return (aptr->sign ? LESS : GREATER);
00167 
00168     if (aptr->sign == bptr->sign)
00169         return (aptr->sign ? abscmp(bptr, aptr) : abscmp(aptr, bptr));
00170 
00171     return (aptr->sign ? LESS : GREATER);
00172 }
00173 
00174 #ifndef ExPeriMental
00175 
00182     static int
00183 abscmp(
00184     Tumbler *aptr,
00185     Tumbler *bptr)
00186 {
00187     int *a, *b;
00188     int i, cmp;
00189 
00190     if (aptr->exp != bptr->exp) {
00191         if (aptr->exp < bptr->exp) {
00192             return LESS;
00193         } else {
00194             return GREATER;
00195         }
00196 
00197     } else {
00198         a = (int *) aptr->mantissa;
00199         b = (int *) bptr->mantissa;
00200         for (i = NPLACES; i--;) {
00201             if (!(cmp = *a++ - *b++)) {
00202             } else if (cmp < 0) {
00203                 return LESS;         /* a < b */
00204             } else {                   /* if (cmp > 0) */
00205                 return GREATER;
00206             }
00207         }
00208     }
00209     return EQUAL;
00210 }
00211 #else
00212 
00219     static int
00220 abscmp(
00221     Tumbler *aptr,
00222     Tumbler *bptr)
00223 {
00224     int *a, *b;
00225     int i, cmp;
00226 
00227     if (aptr->exp != bptr->exp) {
00228         if (aptr->exp < bptr->exp) {
00229             return LESS;
00230         } else {
00231             return GREATER;
00232         }
00233     } else {
00234         a = (int *) aptr->mantissa;
00235         b = (int *) bptr->mantissa;
00236         for (i = NPLACES; i--;) {
00237             cmp = *a - *b;
00238             if (cmp == 0) {            /* this is an efficiency hack */
00239                 a++;
00240                 b++;
00241                 continue;
00242             } else if (cmp < 0) {
00243                 return LESS;         /* a < b */
00244             } else {                   /* if (cmp > 0) */
00245                 return GREATER;
00246             }
00247         }
00248     }
00249     return EQUAL;
00250 }
00251 #endif
00252 
00260     int
00261 intervalcmp(
00262     Tumbler *left,
00263     Tumbler *right,
00264     Tumbler *address)
00265 {
00266     int cmp;
00267 
00268     cmp = tumblercmp(address, left);
00269     if (cmp == LESS)
00270         return TOMYLEFT;
00271 
00272     else if (cmp == EQUAL)
00273         return ONMYLEFTBORDER;
00274 
00275     cmp = tumblercmp(address, right);
00276     if (cmp == LESS)
00277         return THRUME;
00278     else if (cmp == EQUAL)
00279         return ONMYRIGHTBORDER;
00280     else
00281         return TOMYRIGHT;
00282 }
00283 
00284 /* bool iszerotumbler(tumblerptr) tumbler *tumblerptr; { return(!(tumblerptr -> mantissa[0])); } */
00285 
00293     bool
00294 tumblercheckptr(
00295     Tumbler *ptr,
00296     int /* typecrum */  *crumptr)
00297 {
00298     bool wrong;
00299     int i;
00300 
00301     wrong = false;
00302     if (ptr->exp > 0) {
00303 #ifndef DISTRIBUTION
00304         L("bad exp ");
00305 #endif
00306         wrong = true;
00307     }
00308 
00309     if (ptr->sign && ptr->mantissa[0] == 0) {
00310 #ifndef DISTRIBUTION
00311         L(" negative zero ");
00312 #endif
00313         wrong = true;
00314     }
00315 
00316     if (ptr->exp && ptr->mantissa[0] == 0) {
00317 #ifndef DISTRIBUTION
00318         L("fucked up non-normalized");
00319 #endif
00320         wrong = true;
00321     }
00322 
00323     if (ptr->mantissa[0] == 0) {
00324         for (i = 1; i < NPLACES; ++i) {
00325             if (ptr->mantissa[i] != 0) {
00326 #ifndef DISTRIBUTION
00327                 L("nonzerozerotumbler");
00328 #endif
00329                 wrong = true;
00330             }
00331         }
00332     }
00333 
00334     for (i = 0; i < NPLACES; ++i) {
00335         if ((int) (ptr->mantissa[i]) < 0) {
00336 #ifndef DISTRIBUTION
00337             L("negative digit");
00338 #endif
00339             wrong = true;
00340         }
00341     }
00342 
00343     if (wrong) {
00344 #ifndef DISTRIBUTION
00345         dumptumbler(ptr);
00346         if (crumptr) {
00347             dump((typecorecrum *) crumptr);
00348         }
00349         L("\n\n invalid tumbler \n\n");
00350         if (crumptr) {
00351             dumpwholetree((typecorecrum *) crumptr);
00352         }
00353         assert(0); // invalid tumbler
00354 #else
00355         assert(0);
00356 #endif
00357         return false;
00358     }
00359 
00360     return true;
00361 }
00362 
00370     bool
00371 tumblercheck(
00372     Tumbler *ptr)
00373 {
00374     return tumblercheckptr(ptr, (int *) NULL);
00375 }
00376 
00384 /* says whether there is no more than a single non-zero ** digit in mantissa */
00385     bool
00386 is1story(
00387     Tumbler *tumblerptr)
00388 {
00389     int i;
00390 
00391     //assert( tumblercheck(tumblerptr) );
00392     
00393     for (i = 1; i < NPLACES; i++)
00394         if (tumblerptr->mantissa[i] != 0)
00395             return false;
00396     return true;
00397 }
00398 
00406     int
00407 nstories(
00408     Tumbler *tumblerptr)
00409 {
00410     int i;
00411 
00412     //assert( tumblercheck(tumblerptr) );
00413     
00414     for (i = NPLACES; i > 0 && tumblerptr->mantissa[--i] == 0; )
00415         ;
00416 
00417     return i + 1;
00418 }
00419 
00427     int
00428 tumblerlength(
00429     Tumbler *tumblerptr)
00430 {
00431     return nstories(tumblerptr) - tumblerptr->exp;
00432 }
00433 
00434 /* int nzeroesintumbler (tumblerptr) tumbler *tumblerptr; { int n, i, count; n = nstories (tumblerptr); for (count = i 
00435  * = 0; i < n; ++i) if (tumblerptr->mantissa[i] == 0) ++count; count -= tumblerptr->exp; return (count); } */
00436 
00444     int
00445 lastdigitintumbler(
00446     Tumbler *tumblerptr)
00447 {
00448     int n, digit;
00449 
00450     n = nstories(tumblerptr);
00451     digit = tumblerptr->mantissa[n - 1];
00452     return digit;
00453 }
00454 
00455 /* --------- Routines below set and change tumblers -------- */
00456 
00464     void
00465 tumblerjustify(
00466     Tumbler *tumblerptr)
00467 {
00468     int i, j;
00469     int shift;
00470     tdigit *mantissaptr;
00471 
00472     mantissaptr = tumblerptr->mantissa;
00473     if (mantissaptr[0] != 0)
00474         return;
00475 
00476     for (shift = 0; mantissaptr[shift] == 0; ++shift) {
00477         if (shift == NPLACES - 1) {
00478             tumblerptr->exp = 0;
00479             tumblerptr->sign = 0;
00480             return;
00481         }
00482     }
00483 
00484     for (i = 0, j = shift; j < NPLACES;)
00485         mantissaptr[i++] = mantissaptr[j++];
00486 
00487     while (i < NPLACES)
00488         mantissaptr[i++] = 0;
00489 
00490     tumblerptr->exp -= shift;
00491 
00492     //assert( tumblercheck(tumblerptr) );
00493 }
00494 
00495     static void
00496 partialtumblerjustify(
00497     Tumbler *tumblerptr)
00498 {
00499     int i, j;
00500     int shift;
00501     tdigit *mantissaptr;
00502 
00503     mantissaptr = tumblerptr->mantissa;
00504 /* test commented out because is done before this routine is called for efficiency */
00505 /* if (mantissaptr[0] != 0) { return; } */
00506     for (shift = 0; mantissaptr[shift] == 0; ++shift) {
00507         if (shift == NPLACES - 1) {
00508             tumblerptr->exp = 0;
00509             tumblerptr->sign = 0;
00510             return;
00511         }
00512     }
00513 
00514     for (i = 0, j = shift; j < NPLACES;)
00515         mantissaptr[i++] = mantissaptr[j++];
00516 
00517     while (i < NPLACES)
00518         mantissaptr[i++] = 0;
00519 
00520     tumblerptr->exp -= shift;
00521 
00522     //assert( tumblercheck(tumblerptr) );
00523 }
00524 
00532     void
00533 tumblercopy(
00534     Tumbler *fromptr,
00535     Tumbler *toptr)
00536 {
00537 /* movmem (fromptr, toptr, sizeof(tumbler)); */
00538     movetumbler(fromptr, toptr);
00539 }
00540 
00541 /* tumblermin (aptr, bptr, cptr) register tumbler *aptr, *bptr, *cptr; { if (tumblercmp (aptr, bptr) == LESS)
00542  * movetumbler (aptr, cptr); else movetumbler (bptr, cptr); } */
00543 
00551     void
00552 tumblermax(
00553     Tumbler *aptr,
00554     Tumbler *bptr,
00555     Tumbler *cptr)
00556 {
00557     if (tumblercmp(aptr, bptr) == GREATER)
00558         movetumbler(aptr, cptr);
00559     else
00560         movetumbler(bptr, cptr);
00561 }
00562 
00570     void
00571 functiontumbleradd(
00572     Tumbler *aptr,
00573     Tumbler *bptr,
00574     Tumbler *cptr)
00575 /* tumbler add is ~50% of cpu so has been */
00576 /* tightened somewhat */
00577 {
00578     if (iszerotumbler(bptr)) {
00579         movetumbler(aptr, cptr);
00580         return;
00581 
00582     } else if (iszerotumbler(aptr)) {
00583         movetumbler(bptr, cptr);
00584         return;
00585 
00586     } else if (aptr->sign == bptr->sign) {
00587         absadd(aptr, bptr, cptr);
00588         cptr->sign = aptr->sign;
00589 /* absadd returns justified result so no need to justify */
00590 /* I'm not so sure of the subtracts, they aren't used much */
00591 /* 
00592  * if(cptr->mantissa[0] == 0){ partialtumblerjustify (cptr); } */
00593     } else if (abscmp(aptr, bptr) == GREATER) {
00594         strongsub(aptr, bptr, cptr);
00595         cptr->sign = aptr->sign;
00596         if (cptr->mantissa[0] == 0) {
00597             partialtumblerjustify(cptr);
00598         }
00599     } else {
00600         weaksub(bptr, aptr, cptr);
00601         cptr->sign = bptr->sign;
00602         if (cptr->mantissa[0] == 0) {
00603             partialtumblerjustify(cptr);
00604         }
00605     }
00606 /* tumblercheck (cptr); */
00607 /* 
00608  * if (cptr->sign) { L("TUMBLERADD NEGATIVE OUTPUT\n");
00609  * dumptumbler(cptr); L("\n"); } */
00610 }
00611 
00619     void
00620 tumblersub(
00621     Tumbler *aptr,
00622     Tumbler *bptr,
00623     Tumbler *cptr)
00624 {
00625     Tumbler temp;
00626 
00627 /* 
00628  * if(aptr->sign || bptr->sign) { L("TUMBLERSUB NEG IN \n");
00629  * dumptumbler(aptr); L(" "); dumptumbler(bptr);
00630  * L("\n"); } */
00631     if (iszerotumbler(bptr))
00632         movetumbler(aptr, cptr);
00633 
00634     else if (tumblereq(aptr, bptr))
00635         tumblerclear(cptr);
00636 
00637     else if (iszerotumbler(aptr)) {
00638         movetumbler(bptr, cptr);
00639         cptr->sign = !cptr->sign;
00640 
00641     } else {
00642         movetumbler(bptr, &temp);
00643         temp.sign = !temp.sign;
00644         tumbleradd(aptr, &temp, cptr);
00645     }
00646     tumblerjustify(cptr);
00647 /* tumblercheck (cptr); */
00648 /* 
00649  * if (cptr->sign) { L("TUMBLERSUB NEGATIVE OUTPUT\n");
00650  * dumptumbler(cptr); L("\n"); } */
00651 
00652 }
00653 
00654 #ifndef ExPeRiMENATL
00655 #endif
00656 
00664     void
00665 absadd(
00666     Tumbler *aptr,
00667     Tumbler *bptr,
00668     Tumbler *cptr)
00669 {
00670     int i, j;
00671     //UNUSED int place;
00672     int temp;
00673     tdigit *ansmant;
00674     tdigit *bmant, *amant;
00675     Tumbler answer;
00676 
00677     i = j = 0;
00678     amant = aptr->mantissa;
00679     bmant = bptr->mantissa;
00680     answer.xvartumbler = 0;
00681     answer.varandnotfixed = 0;
00682     answer.sign = 0;
00683     ansmant = answer.mantissa;
00684 
00685     if (aptr->exp == bptr->exp) {
00686         answer.exp = aptr->exp;
00687         ansmant[0] = amant[0] + bmant[0];
00688         i = j = 1;
00689 
00690     } else if (aptr->exp > bptr->exp) {
00691         answer.exp = aptr->exp;
00692         temp = aptr->exp - bptr->exp;
00693         while (i < temp) {
00694             ansmant[j++] = amant[i++];
00695         }
00696         ansmant[j++] = amant[i++] + bmant[0];
00697         i = 1;
00698 
00699     } else {
00700         answer.exp = bptr->exp;
00701         temp = bptr->exp - aptr->exp;
00702         while (i <= temp) {
00703             ansmant[j++] = bmant[i++];
00704         }
00705     }
00706 
00707     while (j <= NPLACES - 1)
00708         ansmant[j++] = bmant[i++];
00709 
00710     movetumbler(&answer, cptr);
00711 }
00712 
00713 #ifdef  OlDVeRsIon
00714 
00721     void
00722 absadd(
00723     Tumbler *aptr,
00724     Tumbler *bptr,
00725     Tumbler *cptr)
00726 {
00727     int i, j;
00728     int place;
00729     int temp;
00730     tdigit *ansmant;
00731     tdigit *bmant, *amant;
00732     Tumbler answer;
00733 
00734     i = j = 0;
00735     amant = aptr->mantissa;
00736     bmant = bptr->mantissa;
00737     tumblerclear(&answer);
00738     ansmant = answer.mantissa;
00739 
00740     if (aptr->exp == bptr->exp) {
00741         answer.exp = aptr->exp;
00742         ansmant[0] = amant[0] + bmant[0];
00743         i = j = 1;
00744 
00745     } else if (aptr->exp > bptr->exp) {
00746         answer.exp = aptr->exp;
00747         temp = aptr->exp - bptr->exp;
00748         while (i < temp)
00749             ansmant[j++] = amant[i++];
00750         ansmant[j++] = amant[i++] + bmant[0];
00751         i = 1;
00752 
00753     } else {
00754         answer.exp = bptr->exp;
00755         temp = bptr->exp - aptr->exp;
00756         while (i <= temp)
00757             ansmant[j++] = bmant[i++];
00758     }
00759 
00760     while (j <= NPLACES - 1)
00761         ansmant[j++] = bmant[i++];
00762 
00763     movetumbler(&answer, cptr);
00764 }
00765 
00766 #endif
00767 
00775     void
00776 strongsub(
00777     Tumbler *aptr,
00778     Tumbler *bptr,
00779     Tumbler *cptr)
00780 {
00781     Tumbler answer;
00782     int i, j;
00783 
00784     tumblerclear(&answer);
00785     if (tumblereq(aptr, bptr)) {
00786         movetumbler(&answer, cptr);
00787         return;
00788     }
00789 
00790     if (bptr->exp < aptr->exp) {
00791         movetumbler(aptr, cptr);
00792         return;
00793     }
00794 
00795     answer.exp = aptr->exp;
00796     for (i = 0; aptr->mantissa[i] == bptr->mantissa[i]; ++i) {
00797         --answer.exp;
00798         if (i >= NPLACES) {
00799             movetumbler(&answer, cptr);
00800             return;
00801         }
00802     }
00803 
00804     answer.mantissa[0] = aptr->mantissa[i] - bptr->mantissa[i];
00805     if (++i >= NPLACES) {
00806         movetumbler(&answer, cptr);
00807         return;
00808     }
00809 
00810     for (j = 1; j < NPLACES && i < NPLACES;)
00811         answer.mantissa[j++] = aptr->mantissa[i++];
00812 
00813     movetumbler(&answer, cptr);
00814 }
00815 
00823     void
00824 weaksub(
00825     Tumbler *aptr,
00826     Tumbler *bptr,
00827     Tumbler *cptr)
00828 {
00829     Tumbler answer;
00830     int i;
00831     int expdiff;
00832 
00833     tumblerclear(&answer);
00834     if (tumblereq(aptr, bptr)) {
00835         movetumbler(&answer, cptr);
00836         return;
00837     }
00838 
00839     answer.exp = aptr->exp;
00840     expdiff = aptr->exp - bptr->exp;
00841 
00842     for (i = 0; i < expdiff; ++i) {
00843         answer.mantissa[i] = aptr->mantissa[i];
00844         if (i >= NPLACES) {
00845             movetumbler(&answer, cptr);
00846             return;
00847         }
00848     }
00849 
00850     answer.mantissa[i] = aptr->mantissa[i] - bptr->mantissa[0];
00851     movetumbler(&answer, cptr);
00852 }
00853 
00861     int
00862 tumblerintdiff(
00863     Tumbler *aptr,
00864     Tumbler *bptr)
00865 {
00866     Tumbler c;
00867 
00868     tumblersub(aptr, bptr, &c);
00869     return c.mantissa[0];
00870 }
00871 
00879     void
00880 tumblerincrement(
00881     Tumbler *aptr,
00882     int      rightshift,
00883     int      bint,
00884     Tumbler *cptr)
00885 {
00886     int idx;
00887 
00888     if (iszerotumbler(aptr)) {
00889         tumblerclear(cptr);
00890         cptr->exp = -rightshift;
00891         cptr->mantissa[0] = bint;
00892         return;
00893     }
00894 
00895     if (aptr != cptr)
00896         movetumbler(aptr, cptr);
00897 
00898     for (idx = NPLACES; aptr->mantissa[--idx] == 0 && idx > 0;)
00899         ;
00900 
00901     if (idx + rightshift >= NPLACES) {
00902 #ifndef DISTRIBUTION
00903         dumptumbler(aptr);
00904         L(" idx = %d  rightshift = %d\n", idx, rightshift);
00905         assert(0); // tumblerincrement overflow
00906 #else
00907         assert(0);
00908 #endif
00909     }
00910 
00911     cptr->mantissa[idx + rightshift] += bint;
00912     tumblerjustify(cptr);
00913 }
00914 
00922     void
00923 tumblertruncate(
00924     Tumbler *aptr,
00925     int      bint,
00926     Tumbler *cptr)
00927 {
00928     Tumbler answer;
00929     int i;
00930 
00931     movetumbler(aptr, &answer);
00932     for (i = answer.exp; i < 0 && bint > 0; ++i, --bint)
00933         ;
00934 
00935     if (bint <= 0)
00936         tumblerclear(&answer);
00937     else
00938         for (; bint < NPLACES; ++bint)
00939             answer.mantissa[bint] = 0;
00940 
00941     tumblerjustify(&answer);
00942     movetumbler(&answer, cptr);
00943 }
00944 
00952     void
00953 prefixtumbler(
00954     Tumbler *aptr,
00955     int      bint,
00956     Tumbler *cptr)
00957 {
00958     Tumbler temp1, temp2;
00959 
00960     tumblerclear(&temp1);
00961     temp1.mantissa[0] = bint;
00962     movetumbler(aptr, &temp2);
00963 
00964     if (!iszerotumbler(&temp2))        /* yuckh! */
00965         temp2.exp -= 1;
00966 
00967     tumbleradd(&temp1, &temp2, cptr);
00968 }
00969 
00977 /* 
00978  * beheadtumbler (aptr, bptr) tumbler *aptr, *bptr; { tumbler temp; int i;
00979  * 
00980  * movetumbler (aptr, &temp); if (temp.exp < 0) ++temp.exp; else { for (i =
00981  * 0; i < NPLACES-1; ++i) temp.mantissa[i] = temp.mantissa[i+1];
00982  * temp.mantissa[NPLACES-1] = 0; } tumblerjustify (&temp); movetumbler
00983  * (&temp, bptr); } */
00984 
00985     void
00986 beheadtumbler(
00987     Tumbler *aptr,
00988     Tumbler *bptr)
00989 {
00990     Tumbler temp;
00991 
00992     movetumbler(aptr, &temp);
00993     ++temp.exp;
00994 
00995     if (aptr->exp == 0)
00996         temp.mantissa[0] = 0;
00997 
00998     tumblerjustify(&temp);
00999     movetumbler(&temp, bptr);
01000 }
01001 
01009     void
01010 docidandvstream2tumbler(
01011     Tumbler *docid,
01012     Tumbler *vstream,
01013     Tumbler *tumbleptr)
01014 {
01015     int i, j;
01016 
01017     movetumbler(docid, tumbleptr);
01018     for (i = NPLACES - 1; i >= 0; i--) {
01019         if (tumbleptr->mantissa[i]) {
01020             ++i;
01021             break;
01022         }
01023     }
01024     for (j = 0; i < NPLACES && j < NPLACES;)
01025         tumbleptr->mantissa[++i] = vstream->mantissa[j++];
01026 }

Generated on Sun Aug 21 04:18:15 2005 for Udanax-Green by doxygen1.3.4