home *** CD-ROM | disk | FTP | other *** search
/ World of A1200 / World_Of_A1200.iso / programs / misc / eval / source / src.lha / bitwise.c < prev    next >
C/C++ Source or Header  |  1993-04-13  |  9KB  |  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.