home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / dos / math / pac / bitwise.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-06-05  |  5.7 KB  |  202 lines

  1. /* bitwise.c */
  2. /**********************************************************************
  3. *    File Name     : bitwise.c
  4. *    Function      : and/or/xor/not/two's complement functions of pac
  5. *    Author        : Istvan Mohos, 1987
  6. ***********************************************************************/
  7.  
  8.  
  9. #include "defs.h"
  10. #include "toktab.h"
  11.  
  12. /* bitwise operators:
  13.    Ignore negative signs, if any.
  14.    Add preceding zeros to match digit count of integral part of numbers.
  15.    Add trailing zeros to match digit count of fractional part of nums.
  16.    Flip bits as appropriate.
  17. */
  18.    
  19. char *
  20. bitwise(oper, operand1, operand2, negflag)
  21. char *operand1, *operand2;
  22. int oper, *negflag;
  23. {
  24.  
  25. #ifdef BITTEST
  26.     static char debug1[LINEMAX], debug2[LINEMAX];
  27.     static
  28. #endif
  29.     char buf1[LINEMAX], buf2[LINEMAX];
  30.  
  31.     static char bitbuf[LINEMAX];
  32.     char *bp = bitbuf;
  33.     char *pt1 = operand1;
  34.     char *pt2 = operand2;
  35.     register char *r1, *r2;
  36.     register int ri;
  37.     int leflen1, leflen2;
  38.     int ritlen1 = 0;
  39.     int ritlen2 = 0;
  40.     int dot1 = 0;
  41.     int dot2 = 0;
  42.     int len_of1, len_of2;
  43.     int maxlef, maxrit;
  44.     static char *fid = "bitwise";
  45.  
  46.     _TR
  47.     *bp++ = Base_str[2];
  48.     *bp++ = ' ';
  49.  
  50.     /* ignore signs */
  51.     *negflag = 0;
  52.     if (*pt1 == '-')
  53.         ++pt1;
  54.     len_of1 = strlen(pt1);
  55.     for (r1 = pt1 + len_of1; --r1 >= pt1;)
  56.         if (*r1 == '.') {
  57.             dot1 = 1;
  58.             break;
  59.         }
  60.     if (!dot1)
  61.        leflen1 = len_of1;
  62.     else {
  63.        leflen1 = r1 - pt1;
  64.        ritlen1 = len_of1 - leflen1 - 1;
  65.     }
  66.     
  67.     switch (oper) {
  68.         default:
  69.         case AND:
  70.         case OR:
  71.         case XOR:
  72.             if (*pt2 == '-')
  73.                 ++pt2;
  74.             len_of2 = strlen(pt2);
  75.             for (r2 = pt2 + len_of2; --r2 >= pt2;)
  76.                 if (*r2 == '.') {
  77.                     dot2 = 2;
  78.                     break;
  79.                 }
  80.             if (!dot2)
  81.                leflen2 = len_of2;
  82.             else {
  83.                leflen2 = r2 - pt2;
  84.                ritlen2 = len_of2 - leflen2 - 2;
  85.             }
  86.         
  87.             maxlef = (leflen1 > leflen2) ? leflen1 : leflen2;
  88.             maxrit = (ritlen1 > ritlen2) ? ritlen1 : ritlen2;
  89.  
  90.             r1 = buf1;
  91.             for (ri = maxlef - leflen1; --ri >= 0; *r1++ = '0');
  92.             strcpy(r1, pt1);
  93.             r1 += len_of1;
  94.             if (dot1 || dot2)
  95.                 *r1++ = '.';
  96.             for (ri = maxrit - ritlen1; --ri >= 0; *r1++ = '0');
  97.             *r1 = '\0';
  98.             r1 = buf1;
  99.  
  100.             r2 = buf2;
  101.             for (ri = maxlef - leflen2; --ri >= 0; *r2++ = '0');
  102.             strcpy(r2, pt2);
  103.             r2 += len_of2;
  104.             if (dot1 || dot2)
  105.                 *r2++ = '.';
  106.             for (ri = maxrit - ritlen2; --ri >= 0; *r2++ = '0');
  107.             *r2 = '\0';
  108.             ri = r2 - buf2; /* not including the null */
  109.             r2 = buf2;
  110.  
  111.             switch (oper) {
  112.                 case AND:
  113.                     for (; --ri >= 0; r1++, r2++, bp++)
  114.                         if (*r1 == '1' && *r2 == '1')
  115.                             *bp = '1';
  116.                         else
  117.                             *bp = '0';
  118.                     break;
  119.                 case OR:
  120.                     for (; --ri >= 0; r1++, r2++, bp++)
  121.                         if (*r1 == '1' || *r2 == '1')
  122.                             *bp = '1';
  123.                         else
  124.                             *bp = '0';
  125.                     break;
  126.                 case XOR:
  127.                     for (; --ri >= 0; r1++, r2++, bp++)
  128.                         if ((*r1 == '1' && *r2 == '0') ||
  129.                             (*r1 == '0' && *r2 == '1'))
  130.                             *bp = '1';
  131.                         else
  132.                             *bp = '0';
  133.                     break;
  134.             }
  135.             *bp = '\0';
  136.             if (dot1 || dot2)
  137.                 *(bitbuf + 2 + maxlef) = '.';
  138.  
  139. #ifdef BITTEST
  140.     strcpy(debug1, pt1);
  141.     strcpy(debug2, pt2);
  142.     if (Trace && Tf != NULL)
  143.         fprintf(Tf,
  144.         "\n<<<%s>>>\n<<<%s>>>\n<<<<%s>>>\n<<<%s>>>\n<<<%s>>>\n",
  145.         debug1, debug2, buf1, buf2, bitbuf);
  146. #endif
  147.  
  148.             TR_
  149.             return(bitbuf);
  150.  
  151.         case TW:
  152.             if (dot1) {
  153.                 TR_
  154.                 return(ZERO);
  155.             }
  156.             if (atoi(pt1) == 0) {
  157.                 strcpy(bp, "-1");
  158.                 TR_
  159.                 return(bitbuf);
  160.             }
  161.             /* case continues */
  162.         case NOT:
  163.  
  164.             /* convert second number (in base 10), to size of
  165.                field in which to evaluate the operand */
  166.             if (*pt2 == '-')
  167.                 ++pt2;
  168.             if ((len_of2 = atoi(pt2)) > LINEMAX - 4 - ritlen1) {
  169.                 TR_
  170.                 return(ZERO);
  171.             }
  172.  
  173.             if (*pt1 == '1' && len_of2 == leflen1)
  174.                 *negflag = 1;
  175.             if (leflen1 > len_of2) {
  176.                 len_of2 = leflen1; 
  177.                 pac_err("field too small");
  178.             }
  179.             r2 = bp;
  180.             for (ri = len_of2; --ri >= 0; *r2++ = '1');
  181.             *r2++ = '.';
  182.             for (ri = ritlen1; --ri >= 0; *r2++ = '1');
  183.             *r2-- = '\0';  /* end of result in bitbuf */
  184.  
  185.             /* on last digit */
  186.             r1 = pt1 + leflen1 + ritlen1 + dot1 -1;
  187.             for (ri = ritlen1; --ri >= 0; r1--, r2--)
  188.                 if (*r1 == '1')
  189.                     *r2 = '0';
  190.             if (dot1)
  191.                 *r2-- = *r1--;
  192.             else
  193.                 *r2-- = '\0';
  194.  
  195.             for (ri = leflen1; --ri >= 0; r1--, r2--)
  196.                 if (*r1 == '1')
  197.                     *r2 = '0';
  198.             TR_
  199.             return(bitbuf);
  200.     }
  201. }
  202.