home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS - Coast to Coast / simteldosarchivecoasttocoast2.iso / calculat / meval113.zip / SRC / BITWISE.C < prev    next >
Text File  |  1993-04-11  |  8KB  |  405 lines

  1. /*
  2. **
  3. ** BITWISE.C    Bit-wise operations on floating point numbers.
  4. **
  5. ** Written 11-15-92 in ANSI C
  6. **
  7. ** Eval is a floating point expression evaluator.
  8. ** This file last updated in version 1.10
  9. ** For the version number, see eval.h
  10. ** Copyright (C) 1993  Will Menninger
  11. **
  12. ** This program is free software; you can redistribute it and/or modify it
  13. ** under the terms of the GNU General Public License as published by the
  14. ** Free Software Foundation; either version 2 of the License, or any
  15. ** later version.
  16. **
  17. ** This program is distributed in the hope that it will be useful, but
  18. ** WITHOUT ANY WARRANTY; without even the implied warranty of
  19. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  20. ** General Public License for more details.
  21. **
  22. ** You should have received a copy of the GNU General Public License along
  23. ** with this program; if not, write to the Free Software Foundation, Inc.,
  24. ** 675 Mass Ave, Cambridge, MA 02139, USA.
  25. **
  26. ** The author until 9/93 can be contacted at:
  27. ** e-mail:     willus@ilm.pfc.mit.edu
  28. ** U.S. mail:  Will Menninger, 45 River St., #2, Boston, MA 02108-1124
  29. **
  30. **
  31. */
  32.  
  33. #include "eval.h"
  34.  
  35. #define DATASIZE    ((DBL_MANT_DIG>>3)+2)
  36.  
  37. typedef unsigned char    uchar;
  38. typedef struct    {
  39.         uchar    data[DATASIZE];
  40.         int    sign;
  41.         int    mask;
  42.         int    numbits;
  43.         int    exponent;
  44.         int    mi;
  45.         } BITARRAY, *BITARRAYPTR;
  46.  
  47. static void dbl_to_ba(double val,BITARRAYPTR ba);
  48. static double ba_to_dbl(BITARRAYPTR ba);
  49. static void change_exp(BITARRAYPTR ba,int newexp);
  50. static void shift_right(BITARRAYPTR ba,int count);
  51. static void shift_left(BITARRAYPTR ba,int count);
  52. static void ba_negate(BITARRAYPTR ba);
  53. static void ba_not(BITARRAYPTR ba);
  54. #ifdef DEBUG
  55. static void print_ba(BITARRAYPTR ba);
  56. #endif
  57.  
  58.  
  59. double not(double val)
  60.  
  61.     {
  62.     BITARRAY    ba;
  63.  
  64.     dbl_to_ba(val,&ba);
  65.     ba_not(&ba);
  66.     ba_negate(&ba);
  67.     ba.sign=!ba.sign;
  68.     return(ba_to_dbl(&ba));
  69.     }
  70.  
  71.  
  72. double or(double val1,double val2)
  73.  
  74.     {
  75.     BITARRAY    ba1,ba2;
  76.     int     i;
  77.  
  78.     dbl_to_ba(val1,&ba1);
  79.     dbl_to_ba(val2,&ba2);
  80.     if (ba1.exponent>ba2.exponent)
  81.     change_exp(&ba2,ba1.exponent);
  82.     else
  83.     change_exp(&ba1,ba2.exponent);
  84.     if (!ba1.sign)
  85.     ba_negate(&ba1);
  86.     if (!ba2.sign)
  87.     ba_negate(&ba2);
  88.     for (i=0;i<=ba1.mi;i++)
  89.     ba1.data[i]|=ba2.data[i];
  90.     ba1.data[ba1.mi]&=ba1.mask;
  91.     if (!ba1.sign || !ba2.sign)
  92.     {
  93.     ba_negate(&ba1);
  94.     ba1.sign=0;
  95.     }
  96.     else
  97.     ba1.sign=1;
  98.     return(ba_to_dbl(&ba1));
  99.     }
  100.  
  101.  
  102. double and(double val1,double val2)
  103.  
  104.     {
  105.     BITARRAY    ba1,ba2;
  106.     int     i;
  107.  
  108.     dbl_to_ba(val1,&ba1);
  109.     dbl_to_ba(val2,&ba2);
  110.     if (ba1.exponent>ba2.exponent)
  111.     change_exp(&ba2,ba1.exponent);
  112.     else
  113.     change_exp(&ba1,ba2.exponent);
  114.     if (!ba1.sign)
  115.     ba_negate(&ba1);
  116.     if (!ba2.sign)
  117.     ba_negate(&ba2);
  118.     for (i=0;i<=ba1.mi;i++)
  119.     ba1.data[i]&=ba2.data[i];
  120.     ba1.data[ba1.mi]&=ba1.mask;
  121.     if (!ba1.sign && !ba2.sign)
  122.     {
  123.     ba_negate(&ba1);
  124.     ba1.sign=0;
  125.     }
  126.     else
  127.     ba1.sign=1;
  128.     return(ba_to_dbl(&ba1));
  129.     }
  130.  
  131.  
  132. double xor(double val1,double val2)
  133.  
  134.     {
  135.     BITARRAY    ba1,ba2;
  136.     int     i;
  137.  
  138.     dbl_to_ba(val1,&ba1);
  139.     dbl_to_ba(val2,&ba2);
  140.     if (ba1.exponent>ba2.exponent)
  141.     change_exp(&ba2,ba1.exponent);
  142.     else
  143.     change_exp(&ba1,ba2.exponent);
  144.     if (!ba1.sign)
  145.     ba_negate(&ba1);
  146.     if (!ba2.sign)
  147.     ba_negate(&ba2);
  148.     for (i=0;i<=ba1.mi;i++)
  149.     ba1.data[i]^=ba2.data[i];
  150.     ba1.data[ba1.mi]&=ba1.mask;
  151.     if ((!ba1.sign && ba2.sign)||(ba1.sign && !ba2.sign))
  152.     {
  153.     ba_negate(&ba1);
  154.     ba1.sign=0;
  155.     }
  156.     else
  157.     ba1.sign=1;
  158.     return(ba_to_dbl(&ba1));
  159.     }
  160.  
  161.  
  162. static void dbl_to_ba(double val,BITARRAYPTR ba)
  163.  
  164.     {
  165.     int     i,j,k,m;
  166.     double  f;
  167.  
  168.     ba->numbits=DBL_MANT_DIG-3;
  169.     ba->mask=0;
  170.     ba->mi=0;
  171.     ba->exponent=0;
  172.     ba->sign=(val>=0.);
  173.     val=fabs(val);
  174.     if (val>0.)
  175.     {
  176.     f=log(val)/log(2.);
  177.     f=floor(f)+1.;
  178.     ba->exponent=f;
  179.     f=val/pow(2.,f);
  180.     f=f+pow(2.,(double)-ba->numbits-1.);
  181.     if (f>=1.)
  182.         {
  183.         ba->exponent++;
  184.         f/=2.;
  185.         }
  186.     }
  187.     else
  188.     f=0.;
  189.     for (i=0;i<DATASIZE;i++)
  190.     ba->data[i]=0;
  191.     for (i=0,j=0,k=128;i<ba->numbits;i++)
  192.     {
  193.     f=f*2.;
  194.     if (f>=1.)
  195.         {
  196.         ba->data[j]|=k;
  197.         f-=1.;
  198.         }
  199.     k>>=1;
  200.     if (!k)
  201.         {
  202.         j++;
  203.         k=128;
  204.         }
  205.     }
  206.     if (k==128)
  207.     {
  208.     ba->mask=255;
  209.     ba->mi=j-1;
  210.     }
  211.     else
  212.     {
  213.     for (k<<=1,m=k;k<128;k<<=1,m|=k);
  214.     ba->mask=m;
  215.     ba->mi=j;
  216.     }
  217.     }
  218.  
  219.  
  220. static double ba_to_dbl(BITARRAYPTR ba)
  221.  
  222.     {
  223.     int     i,j,k;
  224.     double  val;
  225.  
  226.     val=0.;
  227.     for (i=0,j=0,k=128;i<ba->numbits;i++,k>>=1)
  228.     {
  229.     if (!k)
  230.         {
  231.         k=128;
  232.         j++;
  233.         }
  234.     val=val*2.;
  235.     if (ba->data[j]&k)
  236.         val=val+1.;
  237.     }
  238.     val=val*pow(2.,(double)ba->exponent-ba->numbits);
  239.     return(ba->sign ? val : -val);
  240.     }
  241.  
  242.  
  243. static void change_exp(BITARRAYPTR ba,int newexp)
  244.  
  245.     {
  246.     if (newexp>ba->exponent)
  247.     shift_right(ba,newexp-ba->exponent);
  248.     else
  249.     shift_left(ba,ba->exponent-newexp);
  250.     ba->exponent=newexp;
  251.     }
  252.  
  253.  
  254. static void shift_right(BITARRAYPTR ba,int count)
  255.  
  256.     {
  257.     int     i,j,k,m;
  258.     int     smallshift;
  259.     int     byteshift;
  260.  
  261.     if (!count)
  262.     return;
  263.     if (count>=ba->numbits)
  264.     {
  265.     for (i=0;i<DATASIZE;i++)
  266.         ba->data[i]=0;
  267.     return;
  268.     }
  269.     smallshift=count&7;
  270.     if (smallshift)
  271.     {
  272.     m=1;
  273.     for (i=1;i<smallshift;i++)
  274.         m=(m<<1)|1;
  275.     k=0;
  276.     for (i=0;i<=ba->mi;i++)
  277.         {
  278.         j=ba->data[i];
  279.         if (i>0)
  280.         ba->data[i]=k|(j>>smallshift);
  281.         else
  282.         ba->data[i]=j>>smallshift;
  283.         k=(j&m)<<(8-smallshift);
  284.         }
  285.     }
  286.     byteshift=(count>>3);
  287.     if (byteshift)
  288.     {
  289.     for (i=ba->mi;i>=byteshift;i--)
  290.         ba->data[i]=ba->data[i-byteshift];
  291.     for (i=byteshift-1;i>=0;i--)
  292.         ba->data[i]=0;
  293.     }
  294.     ba->data[ba->mi]&=ba->mask;
  295.     }
  296.  
  297.  
  298. static void shift_left(BITARRAYPTR ba,int count)
  299.  
  300.     {
  301.     int     i,j,k,m;
  302.     int     smallshift;
  303.     int     byteshift;
  304.  
  305.     if (!count)
  306.     return;
  307.     if (count>=ba->numbits)
  308.     {
  309.     for (i=0;i<DATASIZE;i++)
  310.         ba->data[i]=0;
  311.     return;
  312.     }
  313.     smallshift=count&7;
  314.     if (smallshift)
  315.     {
  316.     m=128;
  317.     for (i=1;i<smallshift;i++)
  318.         m=(m>>1)|128;
  319.     k=0;
  320.     ba->data[ba->mi]&=ba->mask;
  321.     for (i=ba->mi;i>=0;i--)
  322.         {
  323.         j=ba->data[i];
  324.         if (i<ba->mi)
  325.         ba->data[i]=k|(j<<smallshift);
  326.         else
  327.         ba->data[i]=j<<smallshift;
  328.         k=(j&m)>>(8-smallshift);
  329.         }
  330.     }
  331.     byteshift=(count>>3);
  332.     if (byteshift)
  333.     {
  334.     for (i=0;i<=ba->mi-byteshift;i++)
  335.         ba->data[i]=ba->data[i+byteshift];
  336.     for (i=ba->mi-byteshift+1;i<=ba->mi;i++)
  337.         ba->data[i]=0;
  338.     }
  339.     ba->data[ba->mi]&=ba->mask;
  340.     }
  341.  
  342.  
  343. static void ba_negate(BITARRAYPTR ba)
  344.  
  345.     {
  346.     int     i,j,k,one;
  347.  
  348.     i=ba->numbits&7;
  349.     if (!i)
  350.     i=8;
  351.     k=128;
  352.     for (j=1;j<i;j++,k>>=1);
  353.     j=ba->mi;
  354.     one=0;
  355.     for (i=ba->numbits-1;i>=0;i--,k<<=1)
  356.     {
  357.     if (k>128)
  358.         {
  359.         k=1;
  360.         j--;
  361.         if (one)
  362.         break;
  363.         }
  364.     if (one)
  365.         ba->data[j]^=k;
  366.     else
  367.         if (ba->data[j]&k)
  368.         {
  369.         one=1;
  370.         if (i==ba->numbits-1)
  371.             ba->data[j]^=k;
  372.         }
  373.     }
  374.     if (i>0)
  375.     for (;j>=0;j--)
  376.         ba->data[j]=~ba->data[j];
  377.     }
  378.  
  379.  
  380.  
  381. static void ba_not(BITARRAYPTR ba)
  382.  
  383.     {
  384.     int     i;
  385.  
  386.     for (i=0;i<=ba->mi;i++)
  387.     ba->data[i]=~ba->data[i];
  388.     ba->data[ba->mi]&=ba->mask;
  389.     }
  390.  
  391.  
  392. #ifdef DEBUG
  393. static void print_ba(BITARRAYPTR ba)
  394.  
  395.     {
  396.     int     i;
  397.  
  398.     printf(ba->sign ? "+" : "-");
  399.     for (i=0;i<ba->mi;i++)
  400.     printf("%02X",(unsigned)ba->data[i]);
  401.     printf("%02X    %d\n",(unsigned)ba->data[ba->mi]&ba->mask,
  402.         ba->exponent);
  403.     }
  404. #endif
  405.