home *** CD-ROM | disk | FTP | other *** search
/ Meeting Pearls 3 / Meeting_Pearls_III.iso / Pearls / texmf / source / TeX / tex / arith.c next >
C/C++ Source or Header  |  1993-11-01  |  5KB  |  245 lines

  1. /* Use new ANSI Standard Lib functions to speed up arithmetic */
  2.  
  3. #include <stdlib.h>    /* for `div_t' and `ldiv_t' structs */
  4.  
  5. #define EXTERN extern
  6. #include "texd.h"
  7.  
  8. /*
  9.  *   Fuer Amiga und andere:
  10.  *
  11.  * ldiv ist eine Division zweier `long'-Werte
  12.  *
  13.  
  14. ldiv_t ldiv(long numer, long denom)
  15. {
  16.   ldiv_t res;
  17.  
  18.   res.quot = numer / denom;
  19.   res.rem = numer - res.quot * denom;
  20.   return res;
  21. }
  22.  
  23.  *
  24.  * ist fuer Amiga im File `ldiv.asm' bzw. ist in der C-Library.
  25.  *
  26.  */
  27.  
  28.  
  29.  
  30. integer half ( integer x )
  31. {
  32.      /* define odd(x)  ((x) % 2)   in "extra.c" */
  33.     /* simpler: odd(x)  ((x) & 1)   is ok for x<0 */
  34.   if ( x & 1 )        /* if ( odd ( x ) ) */
  35.     return ( x + 1 ) / 2;
  36.   else
  37.     return x / 2;
  38. }
  39.  
  40. #if 0
  41. scaled rounddecimals ( smallnumber k )
  42. { integer a;
  43.  
  44.   a = 0 ; 
  45.   while ( k > 0 ) {
  46.     decr ( k ) ; 
  47.     a = ( a + dig [ k ] * two ) / 10 ; 
  48.   } 
  49.   return ( a + 1 ) / 2 ; 
  50. }
  51. #endif
  52.  
  53. void printscaled ( scaled s )
  54. { printscaled_regmem 
  55.   scaled delta;
  56.  
  57.   if ( s < 0 ) {
  58.     printchar ( 45 ) ; 
  59.     s = - (integer) s ; 
  60.   }
  61.  
  62.   printint ( s / unity ) ; 
  63.   printchar ( 46 ) ; 
  64.   s = TEN_MULT( s % unity ) + 5 ; 
  65.   delta = 10 ; 
  66.   do {
  67.     if ( delta > unity ) 
  68.       s = s - 17232 ; 
  69.     printchar ( 48 + ( s / unity ) ) ; 
  70.     s = TEN_MULT( s % unity ) ; 
  71.     delta = TEN_MULT(delta) ; 
  72.   } while ( s > delta ) ; 
  73. }
  74.  
  75. scaled multandadd ( integer n, scaled x, scaled y, scaled maxanswer )
  76. { multandadd_regmem 
  77.  
  78.   if ( n < 0 ) {
  79.     x = - (integer) x;
  80.     n = - (integer) n;
  81.   }
  82.   if ( n == 0 ) 
  83.     return y;
  84.  
  85.   if ( ( x <= (maxanswer-y)/n ) && ( - (integer) x <= (maxanswer+y)/n ) )
  86.     return ( n * x + y );
  87.  
  88.   aritherror = true ; 
  89.   return 0;
  90.  
  91.  
  92. scaled xovern ( scaled x, integer n )
  93. { register int negative = false;    /* was "boolean" */
  94.   ldiv_t r;
  95.  
  96.   if ( n == 0 ) {
  97.     aritherror = true ;
  98.     remainder = x ;
  99.     return 0 ;
  100.   }
  101.  
  102.   if ( n < 0 ) {
  103.       x = - (integer) x ; 
  104.       n = - (integer) n ; 
  105.       negative = true ; 
  106.   }
  107.   if ( x >= 0 ) {
  108.       r = ldiv(x, n);
  109.       if( negative )
  110.     r.rem = - r.rem;
  111.       remainder = (integer) r.rem;
  112.       return( (integer) r.quot );
  113.   } else {
  114.       x = - (integer) x;
  115.       r = ldiv(x, n);
  116.       if( ! negative )
  117.     r.rem = - r.rem;
  118.       remainder = (integer) r.rem;
  119.       return( - (integer) r.quot );
  120.   }
  121. }
  122.  
  123.  
  124. scaled xnoverd ( scaled xs, integer int_n, integer int_d )
  125. { xnoverd_regmem
  126.   register unsigned long n = int_n;    /* GCC is better with this */
  127.   register unsigned long d = int_d;
  128.   register int positive;    /* was "boolean" */
  129.   nonnegativeinteger t, u, v;
  130.   unsigned long x;
  131.   ldiv_t r;
  132.  
  133.   if ( xs >= 0 )
  134.     positive = true;
  135.   else {
  136.     xs = - (integer) xs;
  137.     positive = false;
  138.   }
  139.  
  140.   /* GCC is better with this ... */
  141.   x = (unsigned long) xs;
  142.  
  143.   /* x is unsigned long,  x%(2^15) is unsigned short, n dto. */
  144.   t = ( x % 32768L ) * n;
  145.   u = ( x / 32768L ) * n + ( t / 32768L );
  146.  
  147.   r = ldiv(u, d);
  148.   v = ( r.rem ) * 32768L + ( t % 32768L );
  149.   if ( r.quot >= 32768L )
  150.     aritherror = true ; 
  151.   else
  152.     u = 32768L * ( r.quot );     /* + ( v / d ) */
  153.  
  154.   r = ldiv(v, d);
  155.   if ( positive ) {
  156.     remainder = r.rem;
  157.     return( (integer) u + r.quot );    /* here is +(v/d) */
  158.   } else {
  159.     remainder = - r.rem;
  160.     return( - ((integer) u + r.quot) );    /* here is +(v/d) */ 
  161.   }
  162. }
  163.  
  164.  
  165. #ifdef atarist
  166. /* GCC 1.37.1 for 68000 is (censored) with  moveq #16,d0  asll d0,d1
  167.  * instead of a simple clrw and swap of the register, so ...
  168.  */
  169. #define SWAP(a)  __asm__ volatile("swap %0" : "=d" (a) : "0" (a) )
  170. #define CLRW(a)  __asm__ volatile ("clrw %0" : "=d" (a) : "0" (a) )
  171. #define EXTL(a)  __asm__ volatile ("extl %0" : "=d" (a) : "0" (a) )
  172. #if 0
  173. #define MULU(a,b) ((b) = (a) * (b))
  174. #else
  175. #define MULU(a,b) \
  176.   __asm__ volatile ("mulu %2,%0" : "=d" (b) : "0" (b), "d,i" (a))
  177. #endif
  178. #endif
  179.  
  180.  
  181. long_halfword badness ( scaled t, scaled s )
  182. { integer r;
  183.   scaled t1;
  184.  
  185.   if ( t == 0 )
  186.     return 0;
  187.  
  188.   if ( s <= 0 ) 
  189.     return infbad;
  190.  
  191.   if ( t <= 7230584L ) {
  192. #ifdef atarist
  193.     /* r = (((unsigned short)(t >> 16)) * 297) << 16;  */
  194.     t1 = t;  SWAP(t1);
  195.     /* r = ((unsigned short) t1 ) * (unsigned short)297; */
  196.     MULU(297,t1); r = t1;
  197.     SWAP(r);  CLRW(r);
  198.  
  199.     /* r += ((unsigned short)(t & 0xffff)) * (unsigned short)297; */
  200.     MULU(297,t); r += t;
  201.     r /= s;
  202. #else
  203.     r = ( t * 297 ) / s ;
  204. #endif
  205.   } else {
  206.     if ( s >= 1663497L ) {
  207.     r = t / ( s / 297 ) ; 
  208.     } else
  209.         /* ==>> (t > 7.230.584  && s < 1.663.497) */
  210.     /* r = t ; */
  211.     return infbad;
  212.   }
  213.  
  214.   if ( r > 1290 ) 
  215.     return infbad;
  216.  
  217. #ifndef atarist
  218.   /* we know: r <= 1290 */
  219.   return( ( ((short)r) * ((short)r) * ((short)r) + 131072L ) / 262144L );
  220. #else
  221.   { unsigned long r1 /* = ((unsigned short) r) * ((unsigned short) r) */ ;
  222.     unsigned long res;
  223.     r1 = r; MULU(r, r1);
  224.  
  225.     /* res = (((unsigned short)(r1 >> 16)) * (unsigned short) r) << 16; */
  226.     res = r1;  SWAP(res);
  227.     /* res = ((unsigned short) res) * ((unsigned short) r); */
  228.     MULU(r, res);
  229.     SWAP(res);  CLRW(res);
  230.  
  231.     /* res += ((unsigned short)(r1 & 0xffff)) * ((unsigned short) r); */
  232.     MULU(r, r1); res += r1;
  233.  
  234. # if 0
  235.     return( ( res + 131072L ) / 262144L );
  236. # else
  237.     res += 131072L;  CLRW(res);  SWAP(res);  return( res >> 2 );
  238. # endif
  239.   }
  240. #endif
  241.  
  242. /* -- end -- */
  243.