/* SYMMETRICA file:lo.c */
#include "def.h"
#include "macro.h"


#define EXP 15
#define LO_B 32768           /*              1000000000000000*/
#define BMINUSEINS 32767     /*               111111111111111*/
#define LO_B1 (INT)2147450880/*111111111111111000000000000000*/
#define B2MINUSEINS (INT)2147483647    /*1000000000000000000000000000000 - 1*/
#define Basis 45
#define MSB  16384 
#define FREE_LOC(a) free_loc(a)

#ifdef LONGINTTRUE
struct ganzdaten gd; /* a global datastructure */
	static OP rl_o; /* obere grenze */
	static OP rl_m; /* modulo */
	static OP rl_x; /* ergebnis */
	static OP rl_a; /* multiplier */
	static INT mem_counter_loc;
	static INT mem_counter_aloc;
#endif

static struct longint * calloclongint();
static INT free_longint();
static INT free_loc();
static INT ganzadd();
static INT ganzanfang();
static INT ganzaus();
static INT ganzdefiniere();
static INT ganzein();
static INT ganzeven();
static INT ganzfziffer();
static INT ganzganzdiv();
static INT ganzhalf();
static INT ganzint();
static INT ganzkopiere();
static INT ganzloesche();
static INT ganzmod();
static INT ganzmul();
static INT ganzneg();
static INT ganzodd();
static INT ganzparam();
static INT ganzquores();
static INT ganzsignum();
static INT ganzsadd();
static INT ganzsmul();
static INT ganzsquores();
static INT ganzvergleich();
static INT ganz1ziffer();
static INT intganz();
static INT locadd();
static INT locdiv();
static INT lochole();
static INT locint();
static INT loclisterette();
static INT locms1();
static INT locmul();
static INT locneg();
static INT locnull();
static INT locodd();
static INT locrette();
static INT locrezliste();
static INT locpsl();
static INT locpsr();
static INT locsadd();
static INT locsdiv();
static INT locsgn();
static INT locsmul();
static INT locssub();
static INT locsub();
static INT locvgl();
static INT retteziffer();

#ifdef LONGINTTRUE
#define GANZSIGNUM(x) ((x)->signum) /* AK 051294 */
#endif /* LONGINTTRUE */

/* dieser Teil wurde von Peter Hain in Karlsruhe
entworfen. Er schrieb diese Langzahl arithmetik in Pascal und
Assembler. In Bayreuth wurden in Form eines Seminars die
Assemblerteile in C geschrieben und spaeter wurde von
Axel Kohnert die restlichen Pascalteile in C uebersetzt.
Die Ein und Ausgabe routinen wurden vollstaendig in Bayreuth
entworfen */

#ifdef LONGINTTRUE
static INT locadd(lx,ly,cy) struct loc *lx,*ly; INT cy;
/* AK 130789 V1.0 */ /* AK 270390 V1.1 */ /* AK 210891 V1.3 */
	{
	static INT hh;
	hh=ly->w0+cy+lx->w0;
	lx->w0=(hh&BMINUSEINS);
	cy = hh >>EXP;
	hh=ly->w1+cy+lx->w1;
	lx->w1=(hh&BMINUSEINS);
	cy = hh >>EXP;
	hh=ly->w2+cy+lx->w2;
	lx->w2=(hh&BMINUSEINS);
	cy = hh >>EXP;
	return((INT)cy);
	}
#endif /* LONGINTTRUE */

#define LOCADD(lx,ly,cy)\
	hh=(ly)->w0+cy+(lx)->w0, (lx)->w0=(hh&BMINUSEINS), cy = hh >>EXP,\
	hh=(ly)->w1+cy+(lx)->w1, (lx)->w1=(hh&BMINUSEINS), cy = hh >>EXP,\
	hh=(ly)->w2+cy+(lx)->w2, (lx)->w2=(hh&BMINUSEINS), cy = hh >>EXP,cy


#define LOCBAS2() Basis
    

#define LOCASS(lx,ly) ((lx)->w2=(ly)->w2,(lx)->w1=(ly)->w1,(lx)->w0=(ly)->w0)

#ifdef LONGINTTRUE
static INT locdiv(qu,rest,dd,dv) struct loc *qu,*rest,*dd,*dv;
/* Division. Bei Eingabe muss gelten: rest<dv.            */
/* (qu,rest) := ((rest*LO_B+dd) DIV dv, (rest*LO_B+dd) MOD dv). */
/* AK 130789 V1.0 */ /* AK 050790 V1.1 */
/* AK 210891 V1.3 */
	{
	INT d6,d5,d4,d3,d2,d1,
	     h6,h5,h4,h3,h2,h1, 
	     m2,m1,m0;


 /* d=rest*B+dd */
 d6=rest->w2; d5=rest->w1; d4=rest->w0; d3=dd->w2; d2=dd->w1; d1=dd->w0;

 /* h=dv */
 h6=(INT)0; h5=(INT)0; h4=(INT)0; h3=dv->w2; h2=dv->w1; h1=dv->w0; 

 /* qu=0 */
 qu->w2=(INT)0; qu->w1=(INT)0; qu->w0=(INT)0;

 /* m=1 */
 m2=(INT)0; m1=(INT)0; m0=(INT)1;

 while /* h<=d */
 (h6 <d6 ||
  (h6==d6 && h5<d5 ) ||
  (h6==d6 && h5==d5 && h4<d4 ) ||
  (h6==d6 && h5==d5 && h4==d4 && h3<d3 ) ||
  (h6==d6 && h5==d5 && h4==d4 && h3==d3 && h2<d2 ) ||
  (h6==d6 && h5==d5 && h4==d4 && h3==d3 && h2==d2 && h1<d1 ) ||
  (h6==d6 && h5==d5 && h4==d4 && h3==d3 && h2==d2 && h1==d1 )
 )
 {
  /* h=h*2 */
  h6=h6<<1; h5=h5<<1; h4=h4<<1; h3=h3<<1; h2=h2<<1; h1=h1<<1; 
  if (h1&LO_B1) {h1=h1&BMINUSEINS; h2++; };
  if (h2&LO_B1) {h2=h2&BMINUSEINS; h3++; };
  if (h3&LO_B1) {h3=h3&BMINUSEINS; h4++; };
  if (h4&LO_B1) {h4=h4&BMINUSEINS; h5++; };
  if (h5&LO_B1) {h5=h5&BMINUSEINS; h6++; };

  /* m=m*2 */
  m2=m2<<1; m1=m1<<1; m0=m0<<1;
  if (m0&LO_B1) {m0=m0&BMINUSEINS; m1++; };
  if (m1&LO_B1) {m1=m1&BMINUSEINS; m2++; };
 }
  while /* d>=dv */
  (d6 >0 || d5>0  || d4>0  ||
   (d6==0 && d5==0 && d4==0 && d3>dv->w2 ) || 
   (d6==0 && d5==0 && d4==0 && d3==dv->w2 && d2>dv->w1 ) || 
   (d6==0 && d5==0 && d4==0 && d3==dv->w2 && d2==dv->w1 && d1>dv->w0 ) ||
   (d6==0 && d5==0 && d4==0 && d3==dv->w2 && d2==dv->w1 && d1==dv->w0 )
  )
  {
   while /*h>d */
   (h6 >d6 ||
    (h6==d6 && h5>d5) ||
    (h6==d6 && h5==d5 && h4>d4) ||
    (h6==d6 && h5==d5 && h4==d4 && h3>d3) ||
    (h6==d6 && h5==d5 && h4==d4 && h3==d3 && h2>d2) ||
    (h6==d6 && h5==d5 && h4==d4 && h3==d3 && h2==d2 && h1>d1 )
   )
   {
    /* h=h/2 */
    if (h6&1) { h6--; h5=h5|LO_B; };  h6=h6>>1;
    if (h5&1) { h5--; h4=h4|LO_B; };  h5=h5>>1;
    if (h4&1) { h4--; h3=h3|LO_B; };  h4=h4>>1;
    if (h3&1) { h3--; h2=h2|LO_B; };  h3=h3>>1;
    if (h2&1) { h2--; h1=h1|LO_B; };  h2=h2>>1;
                                   h1=h1>>1;

    /* m=m/2 */
    if (m2&1) { m2--; m1=m1|LO_B; };  m2=m2>>1;
    if (m1&1) { m1--; m0=m0|LO_B; };  m1=m1>>1;
                                   m0=m0>>1;
   }
   
   /* d=d-h */
   if (h1>d1) { d1=d1+LO_B; d2--; };  d1=d1-h1;
   if (h2>d2) { d2=d2+LO_B; d3--; };  d2=d2-h2;
   if (h3>d3) { d3=d3+LO_B; d4--; };  d3=d3-h3;
   if (h4>d4) { d4=d4+LO_B; d5--; };  d4=d4-h4;
   if (h5>d5) { d5=d5+LO_B; d6--; };  d5=d5-h5;
                                   d6=d6-h6;

   /* qu=qu+m */
   qu->w0=qu->w0|m0; qu->w1=qu->w1|m1; qu->w2=qu->w2|m2;
  }
	rest->w2=d3; rest->w1=d2; rest->w0=d1;
	return(OK);
}
#endif /* LONGINTTRUE */

#ifdef LONGINTTRUE
static INT locint(lx,i) struct loc *lx; INT    i;
/* Umwandlung Integer in loc: lx:=abs(i); locint:=sgn(i)  */
/* AK 130789 V1.0 */ /* AK 150290 V1.1 */
/* AK 210891 V1.3 */
	{
	INT s;

	if (i<(INT)0) 		{s=(INT)-1; i=0-i;}
	else if (i>(INT)0) 		{s=(INT)1;}
	else 			{s=(INT)0;}

	lx->w0=i & BMINUSEINS;
	lx->w1=(i & LO_B1)>>EXP; 
	lx->w2=(lx->w1 & LO_B1)>>EXP;
	lx->w1=lx->w1 & BMINUSEINS;
	return(s);
	}
#endif /* LONGINTTRUE */


#define LOCMAX(lx) ((lx)->w0=BMINUSEINS,\
	(lx)->w1=BMINUSEINS,(lx)->w2=BMINUSEINS)

#ifdef LONGINTTRUE
static INT locms1(lx) struct loc *lx;
/* AK 130789 V1.0 */ /* AK 080390 V1.1 */ /* AK 210891 V1.3 */
	{
	INT j,c,cc;

	c=Basis; cc=(INT)1;
    for (j=(INT)14; (j >=(INT)0) && cc ; j--)
    {
      if ( lx->w2 & ( (INT)1 << j )) 
         cc=(INT)0;
      c--;
    } 
  if (cc) 
    for (j=(INT)14; (j >=(INT)0) && cc ; j--)
    {
      if ( lx->w1 & ( (INT)1 << j )) 
         cc=(INT)0;
      c--;
    }
  if (cc) 
    for (j=(INT)14; (j >=(INT)0) && cc ; j--)
    {
      if ( lx->w0 & ( (INT)1 << j )) 
         cc=(INT)0;
      c--;
    }
  if (cc) 
	{
	fprintf(stderr,"cc=%ld %ld %ld %ld\n",cc,lx->w0,lx->w1,lx->w2);
	error("internal error:LO7");
	}
  return(c);
 }
#endif /* LONGINTTRUE */

 
#ifdef LONGINTTRUE
static INT locmul(ly,lx,la,lb) struct loc *lx,*ly,*la,*lb;
/* AK 130789 V1.0 */ /* AK 260390 V1.1 */ /* AK 210891 V1.3 */
{
static INT hh;
#define teile(z) (hh=(z)>>EXP, (z) &= BMINUSEINS, hh)
/* AK 260390 */

 lx->w0 =                          la->w0 * lb->w0;
 lx->w1 =          teile(lx->w0) + la->w1 * lb->w0;
 lx->w2 =          teile(lx->w1) + la->w2 * lb->w0;
 ly->w0 =          teile(lx->w2)                  ;
 lx->w1 +=                  la->w0 * lb->w1;
 lx->w2 +=  teile(lx->w1) + la->w1 * lb->w1;
 ly->w0 +=  teile(lx->w2) + la->w2 * lb->w1;
 ly->w1 =          teile(ly->w0)                  ;
 lx->w2 +=                  la->w0 * lb->w2;
 ly->w0 +=  teile(lx->w2) + la->w1 * lb->w2;
 ly->w1 +=  teile(ly->w0) + la->w2 * lb->w2;
 ly->w2 =          teile(ly->w1)                  ;
 return OK;
}
#endif /* LONGINTTRUE */

#define LOCMUL(ly,lx,la,lb) /* hh ist noetig */\
 (lx)->w0 =                          (la)->w0 * (lb)->w0,\
 (lx)->w1 =          teile((lx)->w0) + (la)->w1 * (lb)->w0,\
 (lx)->w2 =          teile((lx)->w1) + (la)->w2 * (lb)->w0,\
 (ly)->w0 =          teile((lx)->w2)                  ,\
 (lx)->w1 +=                  (la)->w0 * (lb)->w1,\
 (lx)->w2 +=  teile((lx)->w1) + (la)->w1 * (lb)->w1,\
 (ly)->w0 +=  teile((lx)->w2) + (la)->w2 * (lb)->w1,\
 (ly)->w1 =          teile((ly)->w0)                  ,\
 (lx)->w2 +=                  (la)->w0 * (lb)->w2,\
 (ly)->w0 +=  teile((lx)->w2) + (la)->w1 * (lb)->w2,\
 (ly)->w1 +=  teile((ly)->w0) + (la)->w2 * (lb)->w2,\
 (ly)->w2 =          teile((ly)->w1)                  

#ifdef LONGINTTRUE
static INT locneg(lx,cy) struct loc *lx; INT cy;
/* AK 130789 V1.0 */ /* AK 050790 V1.1 */ /* AK 210891 V1.3 */
	{
if ((cy==(INT)0)&&(lx->w0==(INT)0)&&(lx->w1==(INT)0)&&(lx->w2==(INT)0)) {
		return((INT)0); }
else

	{
	lx->w0 ^= BMINUSEINS;
	lx->w1 ^= BMINUSEINS;
	lx->w2 ^= BMINUSEINS;
	if (cy ==(INT)0 )
	  { ++lx->w0;
	  if (lx->w0 & LO_B)
	    {
	    ++lx->w1;
	    lx->w0 &= BMINUSEINS;
	    if (lx->w1 & LO_B)
	      { ++lx->w2; lx->w1 &= BMINUSEINS; }
            }
          }
       return((INT)1);
       }
  } /* locneg */
#endif /* LONGINTTRUE */

#ifdef LONGINTTRUE
static INT locnull(lx) struct loc *lx;
/* AK 130789 V1.0 */ /* AK 050790 V1.1 */
/* AK 210891 V1.3 */
	{
	lx->w2 =(INT)0; lx->w1 =(INT)0; lx->w0 =(INT)0;
	return OK;
	}  /* Ende von locnull */
#endif /* LONGINTTRUE */

#define LOCNULL(lx) ((lx)->w0=(INT)0,(lx)->w1=(INT)0,(lx)->w2=(INT)0)

#ifdef LONGINTTRUE
static INT locodd(lx) struct loc *lx;
/*locodd:=lx ist ungerade */
/* AK 130789 V1.0 */ /* AK 050790 V1.1 */ /* AK 210891 V1.3 */
	{
	return (INT) (lx->w0 & 1);
	}
#endif /* LONGINTTRUE */


#ifdef LONGINTTRUE
static INT locpsl(lx,ly,a) struct loc *lx,*ly; INT a;
/* AK 130789 V1.0 */ /* AK 050790 V1.1 */ /* AK 210891 V1.3 */
	{
   INT s1,s2,s3,s4,s5,i;
   static struct loc lyy;


   lyy.w0 = ly->w0; lyy.w1 = ly->w1; lyy.w2 = ly->w2;

   if ( a >= Basis) error("internal error:LO8");
   for (i=(INT)1; i <= a;i++)
   {
     s1= (lyy.w0 & MSB) >> 14;
     s2= (lyy.w1 & MSB) >> 14;
     s3= (lyy.w2 & MSB) >> 14;
     s4= (lx->w0 & MSB) >> 14;
     s5= (lx->w1 & MSB) >> 14;
     lyy.w0 = lyy.w0 << 1;
     lyy.w1 = (lyy.w1 << 1) | s1;
     lyy.w2 = (lyy.w2 << 1) | s2;
     lx->w0 = (lx->w0 << 1) | s3;
     lx->w1 = (lx->w1 << 1) | s4;
     lx->w2 = (lx->w2 << 1) | s5;
   }
   lx->w0 = lx->w0 & BMINUSEINS;
   lx->w1 = lx->w1 & BMINUSEINS;
   lx->w2 = lx->w2 & BMINUSEINS;
   return OK;
 } /* Ende von locpsl */
#endif /* LONGINTTRUE */
     
#ifdef LONGINTTRUE
static INT locpsr(lx,ly,a) struct loc *lx,*ly; INT a;
/* AK 130789 V1.0 */ /* AK 050790 V1.1 */ /* AK 210891 V1.3 */
 {
   INT s1,s2,s3,s4,s5,i;
   struct loc lxx;


   lxx.w0 = lx->w0; lxx.w1 = lx->w1; lxx.w2 = lx->w2;


   if ( a >= Basis) error("internal error:LO9");
   for (i=(INT)1; i <= a;i++)
   {
     s1= (ly->w1 & 1) << 14;
     s2= (ly->w2 & 1) << 14;
     s3= (lxx.w0 & 1) << 14;
     s4= (lxx.w1 & 1) << 14;
     s5= (lxx.w2 & 1) << 14;
     ly->w0 = (ly->w0 >> 1) | s1;
     ly->w1 = (ly->w1 >> 1) | s2;
     ly->w2 = (ly->w2 >> 1) | s3;
     lxx.w0 = (lxx.w0 >> 1) | s4;
     lxx.w1 = (lxx.w1 >> 1) | s5;
     lxx.w2 = (lxx.w2 >> 1);
   }
   return OK;
 } /* Ende von locpsr */
#endif /* LONGINTTRUE */

#ifdef LONGINTTRUE
static INT locsadd(lx,i) struct loc *lx; INT i;
/* AK 130789 V1.0 */ /* AK 050790 V1.1 */ /* AK 210891 V1.3 */
{
	INT cy,hh;
	if (i<(INT)0) i=(-i);
	hh=lx->w0+(i%LO_B);
	lx->w0=(hh & BMINUSEINS);
	cy = hh >>EXP;
	hh=lx->w1+(i/LO_B)+cy;
	lx->w1=(hh & BMINUSEINS);
	cy = hh >>EXP;
	hh=lx->w2+cy;
	lx->w2=(hh & BMINUSEINS);
	cy = hh >>EXP;
	return(cy);
	}
#endif /* LONGINTTRUE */


#ifdef LONGINTTRUE
static INT locsdiv(qu,di,dd,dv) struct loc *qu,*dd; INT di,dv;
/* Division. Bei Eingabe muss gelten: di<dv.             */
/* (locsdiv,qu) := ((di*B+dd) MOD dv, (di*B+dd) DIV dv). */
/* AK 130789 V1.0 */ /* AK 030790 V1.1 */ /* AK 210891 V1.3 */
	{
 INT d6,d5,d4,d3,d2,d1,
     h6,h5,h4,h3,h2,h1, 
     m2,m1,m0,
     dv2,dv1,dv0;

 /* di umwandeln */
 if (di<(INT)0) 
	return error("internal error:LO10");
 d4=di & BMINUSEINS;
 d5=(di & LO_B1)>>EXP; 
 d6=(d5 & LO_B1)>>EXP;
 d5=d5 & BMINUSEINS;

 /* dv umwandeln */
 if (dv<(INT)0) 
	return error("internal error:LO11");
 dv0=dv & BMINUSEINS;
 dv1=(dv & LO_B1)>>EXP; 
 dv2=(dv1 & LO_B1)>>EXP;
 dv1=dv1 & BMINUSEINS;

 /* d=di*B+dd */
 d3=dd->w2; d2=dd->w1; d1=dd->w0;

 /* h=dv */
 h6=(INT)0; h5=(INT)0; h4=(INT)0; h3=dv2; h2=dv1; h1=dv0; 

 /* qu=0 */
 qu->w2=(INT)0; qu->w1=(INT)0; qu->w0=(INT)0;

 /* m=1 */
 m2=(INT)0; m1=(INT)0; m0=(INT)1;

 while /* h<=d */
 (h6 <d6 ||
  (h6==d6 && h5<d5 ) ||
  (h6==d6 && h5==d5 && h4<d4 ) ||
  (h6==d6 && h5==d5 && h4==d4 && h3<d3 ) ||
  (h6==d6 && h5==d5 && h4==d4 && h3==d3 && h2<d2 ) ||
  (h6==d6 && h5==d5 && h4==d4 && h3==d3 && h2==d2 && h1<d1 ) ||
  (h6==d6 && h5==d5 && h4==d4 && h3==d3 && h2==d2 && h1==d1) 
 )
 {
	  /* h=h*2 */
	  h6=h6<<1; h5=h5<<1; h4=h4<<1; h3=h3<<1; h2=h2<<1; h1=h1<<1; 
	  if (h1&LO_B1) {h1&=BMINUSEINS; h2++; };
	  if (h2&LO_B1) {h2&=BMINUSEINS; h3++; };
	  if (h3&LO_B1) {h3&=BMINUSEINS; h4++; };
	  if (h4&LO_B1) {h4&=BMINUSEINS; h5++; };
	  if (h5&LO_B1) {h5&=BMINUSEINS; h6++; };

	  /* m=m*2 */
	  m2=m2<<1; m1=m1<<1; m0=m0<<1;
	  if (m0&LO_B1) {m0&=BMINUSEINS; m1++; };
	  if (m1&LO_B1) {m1&=BMINUSEINS; m2++; };
 }
  while /* d>=dv */
  (d6 >(INT)0 || d5>(INT)0  || d4>(INT)0  ||
   (d6==(INT)0 && d5==(INT)0 && d4==(INT)0 && d3>dv2 ) || 
   (d6==(INT)0 && d5==(INT)0 && d4==(INT)0 && d3==dv2 && d2>dv1 ) || 
   (d6==(INT)0 && d5==(INT)0 && d4==(INT)0 && d3==dv2 && d2==dv1 && d1>dv0 ) ||
   (d6==(INT)0 && d5==(INT)0 && d4==(INT)0 && d3==dv2 && d2==dv1 && d1==dv0 )
  )
  {
		   while /*h>d */
		   (h6 >d6 ||
		    (h6==d6 && h5>d5) ||
		    (h6==d6 && h5==d5 && h4>d4) ||
		    (h6==d6 && h5==d5 && h4==d4 && h3>d3) ||
		    (h6==d6 && h5==d5 && h4==d4 && h3==d3 && h2>d2) ||
		    (h6==d6 && h5==d5 && h4==d4 && h3==d3 && h2==d2 && h1>d1 )
		   )
		   {
			    /* h=h/2 */
			    if (h6&1) { h6--; h5|=LO_B; };  h6=h6>>1;
			    if (h5&1) { h5--; h4|=LO_B; };  h5=h5>>1;
			    if (h4&1) { h4--; h3|=LO_B; };  h4=h4>>1;
			    if (h3&1) { h3--; h2|=LO_B; };  h3=h3>>1;
			    if (h2&1) { h2--; h1|=LO_B; };  h2=h2>>1;
							   h1=h1>>1;

			    /* m=m/2 */
			    if (m2&1) { m2--; m1=m1|LO_B; };  m2=m2>>1;
			    if (m1&1) { m1--; m0=m0|LO_B; };  m1=m1>>1;
							   m0=m0>>1;
		   }
		   
		   /* d=d-h */
		   if (h1>d1) { d1+=LO_B; d2--; };  d1-=h1;
		   if (h2>d2) { d2+=LO_B; d3--; };  d2-=h2;
		   if (h3>d3) { d3+=LO_B; d4--; };  d3-=h3;
		   if (h4>d4) { d4+=LO_B; d5--; };  d4-=h4;
		   if (h5>d5) { d5+=LO_B; d6--; };  d5-=h5;
						 d6-=h6;

		   /* qu=qu+m */
		   qu->w0|=m0; qu->w1|=m1; qu->w2|=m2;
  }
  d3=d3<<EXP|d2;
  d3=d3<<EXP|d1;
  return(d3);
	}
#endif /* LONGINTTRUE */

#ifdef LONGINTTRUE
static INT locsgn(lx) struct loc *lx;
/* AK 130789 V1.0 */ /* AK 050790 V1.1 */ /* AK 210891 V1.3 */
	{
	  if (lx->w2 || lx->w1 || lx->w0 ) 
	     return (INT) 1;
	  else return (INT) 0;
	} /* Ende locsgn */
#endif /* LONGINTTRUE */


#ifdef LONGINTTRUE
static INT locsmul(lx,i,ue) struct loc *lx; INT i,ue;
/* AK 130789 V1.0 */ /* AK 050790 V1.1 */ /* AK 210891 V1.3 */
	{
	INT cy,h0,h1,h2,i0,i1,i2,u0,u1,u2;
	if (i<0)  {i=~i;++i;}
	if (ue<0) {ue=~ue;++ue;} 
	i0=i&BMINUSEINS; i1=((i&LO_B1)>>15); i2=((i&(B2MINUSEINS+1))>>30);
	u0=ue&BMINUSEINS; u1=((ue&LO_B1)>>15); u2=((ue&(B2MINUSEINS+1))>>30);
	h0=(lx->w0)*i0+u0;
		cy = (h0 >> 15);
		h0 &= BMINUSEINS;
	h1=(lx->w0)*i1+(lx->w1)*i0+cy+u1;
		cy = (h1 >> 15);
		h1 &= BMINUSEINS;
	h2=(lx->w0)*i2+(lx->w1)*i1+(lx->w2)*i0+cy+u2;
	cy = (h2 >> 15);
	h2 &= BMINUSEINS;
	cy += (lx->w1)*i2+(lx->w2)*i1+(((lx->w2)*i2)<<15);
	lx->w0 = h0; lx->w1 = h1; lx->w2 = h2;
	return(cy);
	}
#endif /* LONGINTTRUE */

#ifdef LONGINTTRUE
static INT locssub(lx,i) struct loc *lx; INT i;
/* AK 130789 V1.0 */ /* AK 050790 V1.1 */ /* AK 210891 V1.3 */
	{
	INT cy;
	if (i<(INT)0) i=(-i);
	lx->w0=lx->w0-(i%LO_B);
	if (lx->w0 < 0) { lx->w0 += LO_B;
			   cy = (INT)1; }
	else cy =(INT)0;
	lx->w1=lx->w1-(i/LO_B)-cy;
	if (lx->w1 < 0) { lx->w1 += LO_B;
			   cy = (INT)1; }
	else cy =(INT)0;
	lx->w2=lx->w2-cy;
	if (lx->w2 < 0) { lx->w2 += LO_B;
			   cy = (INT)1; }
	else cy = (INT)0;
	return(cy);
	}
#endif /* LONGINTTRUE */

#ifdef LONGINTTRUE
static INT locsub(lx,ly,cy) struct loc *lx,*ly; INT cy;
/* AK 130789 V1.0 */ /* AK 050790 V1.1 */ /* AK 210891 V1.3 */
{
	lx->w0=lx->w0- ly->w0 -cy;
	if (lx->w0 <(INT)0) { lx->w0 += LO_B;
			   cy = (INT)1; }
	else cy =(INT)0;
	lx->w1=lx->w1- ly->w1- cy;
	if (lx->w1 <(INT)0) { lx->w1 += LO_B;
			   cy = (INT)1; }
	else cy =(INT)0;
	lx->w2=lx->w2- ly->w2- cy;
	if (lx->w2 <(INT)0) { lx->w2 += LO_B;
			   cy = (INT)1; }
	else cy =(INT)0;
	return(cy);
}
#endif /* LONGINTTRUE */

#ifdef LONGINTTRUE
static INT locvgl(lx,ly) struct loc *lx,*ly;
/* AK 130789 V1.0 */ /* AK 050790 V1.1 */ /* AK 210891 V1.3 */
	{
	  if (lx->w2 > ly->w2) return((INT)1);
	    else if (lx->w2 < ly->w2 ) return (INT)-1;
	    else if (lx->w1 > ly->w1) return((INT)1);
	    else if (lx->w1 < ly->w1) return (INT)-1;
	    else if (lx->w0 > ly->w0) return((INT)1);
	    else if (lx->w0 < ly->w0) return (INT)-1;
	    else return((INT)0); 
	}  /* Ende locvgl */
#endif /* LONGINTTRUE */



#ifdef LONGINTTRUE
static INT ganzadd(x,y) struct longint *x,*y;
/* AK: Fri Jan 13 07:24:17 MEZ 1989 */
/* dieser Teil wurde von Peter Hain in Karlsruhe
entworfen. Er schrieb diese Langzahl arithmetik in Pascal und
Assembler. In Bayreuth wurden in Form eines Seminars die
Assemblerteile in C geschrieben und spaeter wurde von
Axel Kohnert die restlichen Pascalteile in C uebersetzt.
Die Ein und Ausgabe routinen wurden vollstaendig in Bayreuth
entworfen */
/* AK 130789 V1.0 */ /* AK 050790 V1.1 */ /* AK 210891 V1.3 */
	{
	struct loc *alocx, *alocy, *lloc, *plocx, *plocy;
	INT	cy,xl,ll;
	signed char xs,ys;

	xs = x->signum; ys = y->signum; xl = x->laenge;
	if (((xs>=(signed char)0) && (ys>=(signed char)0)) || 
			((xs<(signed char)0) && (ys<(signed char)0)))
		{ alocx = x->floc; alocy = y->floc; cy = 0;
		do	{ cy = locadd(alocx,alocy,cy);
			plocx = alocx; plocy = alocy; alocx = alocx->nloc;
			alocy = alocy->nloc; }
		while ((alocx != NULL) && (alocy != NULL));

		/* fuege rest an */
		if (alocy != NULL)
			{ do 	{ lochole(&alocx); plocx->nloc = alocx;
				xl++; cy = locadd(alocx,alocy,cy);
				plocx = alocx; alocx = NULL; plocy = alocy;
				alocy = alocy->nloc; }
			while (alocy != NULL);
			}
		else	{ while ((alocx != NULL) && (cy != 0))
				{ cy = locsadd(alocx,cy); plocx = alocx;
				alocx = alocx->nloc; }
			}

		/* noch ein cy? */
		if (cy != 0)
			{ lochole(&alocx);
			plocx->nloc = alocx; locint(alocx,cy); xl++; }
		if (xs == 0) xs = ys;
		} /* end of first if */
	else	{
		alocx = x->floc; alocy = y->floc; cy = 0;
		/* subtract y from x */
		do	{ cy = locsub(alocx,alocy,cy); plocx = alocx;
			alocx = alocx->nloc; plocy = alocy; alocy = alocy->nloc;
			}
		while ((alocx != NULL) && (alocy != NULL));

		/* append the remaining part */
		if (alocy != NULL)
			{
			do 	{ lochole(&alocx); plocx->nloc = alocx; xl++;
				cy = locsub(alocx,alocy,cy); plocx = alocx;
				alocx = NULL;plocy = alocy;alocy = alocy->nloc;
				}
			while (alocy != NULL);
			}
		else 	{
			while	((alocx != NULL) && (cy != 0))
				{ cy = locssub(alocx,cy);
				plocx = alocx; alocx = alocx->nloc; }
			};

		/* normieren  von x */
		if (cy != 0)
			{
			alocx = x->floc; lloc = NULL; ll = 1; cy = 0;
			do 	{ cy = locneg(alocx,cy);
				if (locsgn(alocx) != 0)
					{ lloc = alocx; xl = ll; }
				alocx = alocx->nloc; ll++;
				}
			while (alocx != NULL);
			loclisterette(&(lloc->nloc)); xs = -xs;
			if (xs == 0) xs = -1;
			}
		else	{
			alocx = x->floc; lloc = NULL; ll = 1;
			do	{
				if (locsgn(alocx) != 0)
					{ lloc = alocx; xl = ll; }
				alocx = alocx->nloc; ll++;
				}
			while (alocx != NULL);
			if (lloc == NULL)
				/* das ergebnis der addition ist null */
				{ loclisterette(&(x->floc->nloc));
				xs = 0; xl =1; }
			else	loclisterette(&(lloc->nloc));
			}
		}
	x->laenge = xl; x->signum = xs;
	return(OK);			
	}
#endif /* LONGINTTRUE */


#ifdef LONGINTTRUE
static INT ganzsquores(x,rest,y) struct longint *x; INT *rest,y;
/* AK Tue Jan 31 07:48:38 MEZ 1989 */
/* dieser Teil wurde von Peter Hain in Karlsruhe
entworfen. Er schrieb diese Langzahl arithmetik in Pascal und
Assembler. In Bayreuth wurden in Form eines Seminars die
Assemblerteile in C geschrieben und spaeter wurde von
Axel Kohnert die restlichen Pascalteile in C uebersetzt.
Die Ein und Ausgabe routinen wurden vollstaendig in Bayreuth
entworfen */
/* AK 130789 V1.0 */ /* AK 200290 V1.1 */ /* AK 210891 V1.3 */
	{

	struct loc *alocx, *blocx, *slocx;
	INT	r;
	signed char sx,sy;

	sx = x->signum;
	if (y>(INT)0) sy=(signed char)1; 
	else if (y<(INT)0) sy = (signed char)-1; 
	else sy=(signed char)0;
	if (y<(INT)0) y = -y;
	blocx = x->floc; x->floc = NULL; locrezliste(&blocx);
	alocx = blocx; slocx = alocx->nloc; r=(INT)0;
	while (slocx != NULL)
		{ r = locsdiv(alocx,r,alocx,y); alocx = slocx;
		slocx = alocx->nloc; }


	r = locsdiv(alocx,r,alocx,y);
	*rest = r * sx;
	if (locsgn(blocx) !=(INT)0) x->signum = sx*sy;
	else if (x->laenge == (INT)1) x->signum = (signed char)0;
	else	{
		alocx = blocx; blocx = blocx->nloc; alocx->nloc =  NULL;
		locrette(&alocx); x->laenge --; x->signum = sx*sy;
		};

	locrezliste(&blocx);
	x->floc = blocx;
	return(OK);
	}
#endif /* LONGINTTRUE */


#ifdef LONGINTTRUE

static INT ganzhalf(x) struct longint *x;
/* AK 021294 */
{
	struct loc *alocx, *plocx;
	alocx = x->floc;
	plocx = NULL;
	while (alocx != NULL)
	{
		alocx->w0 = alocx->w0 >> 1;
		alocx->w0 = alocx->w0 | ( (alocx->w1 & 1) << 14);
		alocx->w1 = alocx->w1 >> 1;
		alocx->w1 = alocx->w1 | ( (alocx->w2 & 1) << 14);
		alocx->w2 = alocx->w2 >> 1;
		if (alocx->nloc != NULL)
			alocx->w2 = alocx->w2 | ( (alocx->nloc->w0 & 1) << 14);
		if (alocx->nloc == NULL)
			{
			if (plocx != NULL)
			if ((alocx->w0 == 0) &&
				(alocx->w1 == 0)&&
				(alocx->w2 == 0))
				{

				free_loc(alocx);
				plocx->nloc = NULL;
				x->laenge = x->laenge - 1;
				return OK;

				}
			}
		
		plocx = alocx;
		alocx = alocx->nloc;
	} 
}

static INT ganzquores(x,rest,y) struct longint *x, *rest, *y; 
/* AK Mon Mar 13 10:58:11 MEZ 1989 */
/* dieser Teil wurde von Peter Hain in Karlsruhe
entworfen. Er schrieb diese Langzahl arithmetik in Pascal und
Assembler. In Bayreuth wurden in Form eines Seminars die
Assemblerteile in C geschrieben und spaeter wurde von
Axel Kohnert die restlichen Pascalteile in C uebersetzt.
Die Ein und Ausgabe routinen wurden vollstaendig in Bayreuth
entworfen */
/* AK 130789 V1.0 */ /* AK 050790 V1.1 */ /* AK 210891 V1.3 */
{
	INT		vgl,cy,cyn,a,i,rl=(INT)0,ql;
	signed char 		sx,sy;
	struct loc 	*alocx, *plocx,*slocx,*blocx,*rlocx,*llocx,
			*alocy,*plocy,*blocy,*blocq,
			*locx2,*locx1,*locx0,*locy1,*locy0;

	struct loc	null,q,r,ov,hi,lo;
	INT		fertig;


if ((x->floc == y->floc) || (x->floc == rest->floc) || (y->floc == rest->floc))
	error("internal error:LO1");

loclisterette(&rest->floc);
sx = x->signum;
sy = y->signum;
if (y->laenge == (INT)1)	/* einfache divison */
	{
	locnull(&null); LOCASS(&lo,y->floc); blocx = x->floc;
	x->floc = NULL; locrezliste(&blocx); alocx = blocx; slocx = alocx->nloc;
	LOCASS(&r,&null);
	while (slocx != NULL)
		{
		locdiv(alocx,&r,alocx,&lo);
		alocx = slocx;
		slocx = slocx->nloc;
		}
	locdiv(alocx,&r,alocx,&lo);
	/* Seite 6 von test.p */
	if (locsgn(&r) ==(INT)0) rest->signum = (signed char)0; 
	else rest->signum = sx;
	lochole(&rest->floc);
	LOCASS(rest->floc,&r);
	rest->laenge = (INT)1;
	if (locsgn(blocx) !=(INT)0) x->signum = sx * sy;
	else if (x->laenge == (INT)1) x->signum = (signed char)0;
	else	{ alocx = blocx; blocx = blocx->nloc; alocx->nloc = NULL;
		locrette(&alocx); x->laenge --; x->signum = sx * sy;
		}
	locrezliste(&blocx);
	x->floc = blocx;
	} /* ende der einfachen division */
else	if (x->laenge < y->laenge)	/* trivial */
	{
	*rest = *x; x->floc = NULL; lochole(&x->floc);
	x->signum = (signed char)0; x->laenge = (INT)1;
	}	/* ende des trivialfalles */
else	{	/* normalfall x->laenge >= y->laenge >= 2 */
		/* lange division */
	locnull(&null); blocy = y->floc; y->floc = NULL;
	locrezliste(&blocy); locy1 = blocy; locy0 = blocy->nloc;
	a = LOCBAS2() - (INT)1 - locms1(locy1);
	locx1 = x->floc; x->floc = NULL; locrezliste(&locx1);
	locx2 = NULL; lochole(&locx2); locx2->nloc = locx1;
	locx0 = locx1->nloc;

	/* dividend und divisor normieren. dividend zerlegen */
	locpsl(locx2,locx1,a);
	alocy = locy0; plocy = locy1; alocx = locx0; plocx = locx1;
	do	{
		locpsl(plocy,alocy,a); 
		locpsl(plocx,alocx,a);
		plocy = alocy; alocy = alocy->nloc;
		plocx = alocx; alocx = alocx->nloc;
		}
	while (alocy != NULL);
	locpsl(plocy,&null,a);

	llocx = plocx;
	rlocx = alocx;

	while (alocx != NULL)	/* rest des dividenden normieren */
		{
		locpsl(plocx,alocx,a);
		plocx = alocx; alocx = alocx->nloc;
		}
	locpsl(plocx,&null,a);

	llocx->nloc = NULL; 	/* dividend getrennt */

	/* listen fuer teildividend und divisor umkehren */
	blocx = locx2; locrezliste(&blocx); locrezliste(&blocy);

	/* quotientenliste mit laenge */
	blocq = NULL; ql =(INT)0;

	do	{	/* divisionsschritt */
		if (locvgl(locx2,locy1) ==(INT)0) LOCMAX(&q);
		else	{
			LOCASS(&r,locx2);
			locdiv(&q,&r,locx1,locy1);
			locmul(&hi,&lo,&q,locy0);
			/* falls (hi,lo) <= (r,locx0):fertig */
			vgl = locvgl(&hi,&r);
			if ((vgl >0) || ((vgl ==(INT)0) && 
						(locvgl(&lo,locx0) >(INT)0)))
				{
				locssub(&q,(INT)1);
				cy = locadd(&r,locy1,(INT)0);
				if (cy ==(INT)0)
					{
					cy = locsub(&lo,locy0,(INT)0);
					if (cy == (INT)1) cy = locssub(&hi,(INT)1);
			/* seite 7 von test.p */
					vgl = locvgl(&hi,&r);
					if (
						(vgl >(INT)0) ||
					 ((vgl ==(INT)0) 
				&& 
	/* bug 050790 */	  (locvgl(&lo,locx0) >(INT)0 )))
						cy = locssub(&q,(INT)1);
					}
				}
			};

	/* subtrahiere q*divisor von teildivdend llocx = vorgaenger locx0 */
		alocy = blocy; alocx = blocx; cy = 0; cyn = 0; locnull(&ov);
		llocx = NULL; plocx = NULL;
		do	{
			locmul(&hi,&lo,alocy,&q);
			cy = locadd(&lo,&ov,cy);
			LOCASS(&ov,&hi);
			cyn = locsub(alocx,&lo,cyn);
			plocx = alocx; alocx = alocx->nloc; alocy = alocy->nloc;
			if (alocx == locx0) llocx = plocx;
			}
		while (alocy != NULL);
		cy = locsadd(&ov,cy); cyn = locsub(alocx,&ov,cyn);
		if (cy !=(INT)0) 
				return error("internal error:LO12");

		/* falls differenz negativ, q war um 1zu gross. korrektur */

		if (cyn == (INT)1)
			{
			cyn = locssub(&q,(INT)1);
			alocx = blocx; alocy = blocy; cy =(INT)0;
			do	{
				cy = locadd(alocx,alocy,cy);
				alocx = alocx->nloc; alocy = alocy->nloc;
				}
			while (alocy != NULL);
			cy = locsadd(alocx,cy); 
			if (cy != (INT)1)  
				return error("internal error:LO13");
			}

		/* quotientenziffer q abspeichern . locx2 ist frei dafuer */
		locx1->nloc = NULL;
		if ((blocq == NULL) && (locsgn(&q) ==(INT)0)) locrette(&locx2);
		else	{
			locx2->nloc = blocq; blocq = locx2; locx2 = NULL;
			LOCASS(blocq,&q); ql ++;
			};

		/* neuer teildividend */
		fertig = (rlocx == NULL);
		if (! fertig)
			{
			alocx = blocx; blocx = rlocx; rlocx = rlocx->nloc;
			blocx->nloc = alocx;
			locx2 = locx1; locx1 = locx0; locx0 = llocx;
			if (locx0 == NULL) locx0 = blocx; 
			}
		}
	while (! fertig);	/* ende divisionsschritt */

	/* quotient */
	if (blocq == NULL)
		{
		lochole (&x->floc); x->signum = (signed char)0;
		x->laenge = (INT)1;
		}
	else	{
		x->floc = blocq; blocq = NULL;
		x->signum = sx * sy; x->laenge = ql;
		}

	/* rest normierung rueckgaengig machen fuehrende nullen entfernen */
	i =(INT)0; llocx = NULL;
	plocx = blocx; alocx = plocx->nloc; 
	do	{
		i++;
	/* Seite 8 von test.p */
		locpsr(alocx,plocx,a);
		if (locsgn(plocx) !=(INT)0) 
			{
			llocx = plocx; rl = i;
			}
		plocx = alocx; alocx = alocx->nloc;
		}
	while (alocx != NULL);
	locpsr(&null,plocx,a);
	if (locsgn(plocx) !=(INT)0) { llocx = plocx; rl = i+ (INT)1; }

	if (llocx == NULL)	/* rest 0 */
		{
		loclisterette(&blocx->nloc); rest->floc = blocx;
		blocx = NULL; rest->signum = (signed char)0; rest->laenge = (INT)1;
		}
	else	{
		loclisterette(&llocx->nloc); rest->floc = blocx;
		blocx = NULL; rest->signum = sx; rest->laenge = rl;
		}

	/* divisor. normierung rueckgaengig machen */
	plocy = blocy; alocy = plocy->nloc;
	do	{ locpsr(alocy,plocy,a); plocy = alocy; alocy = alocy->nloc; }
	while (alocy != NULL);
	locpsr(&null,plocy,a); y->floc = blocy; blocy = NULL;
	} /* lange divison */
return(OK);
} /* ende ganzquores */
#endif /* LONGINTTRUE */

	
#ifdef LONGINTTRUE
static INT ganzganzdiv(x,y) struct longint *x,*y;
/* AK: Tue Mar 14 09:03:44 MEZ 1989 */
/* dieser Teil wurde von Peter Hain in Karlsruhe
entworfen. Er schrieb diese Langzahl arithmetik in Pascal und
Assembler. In Bayreuth wurden in Form eines Seminars die
Assemblerteile in C geschrieben und spaeter wurde von
Axel Kohnert die restlichen Pascalteile in C uebersetzt.
Die Ein und Ausgabe routinen wurden vollstaendig in Bayreuth
entworfen */
/* AK 130789 V1.0 */ /* AK 210891 V1.3 */
	{
	struct longint rest;

	rest.floc = NULL; ganzquores(x,&rest,y); 
	return ganzloesche(&rest);
	}
#endif /* LONGINTTRUE */

#ifdef LONGINTTRUE
static INT ganzmod(x,rest,y) struct longint *x,*y,*rest;
/* AK Tue Mar 14 09:05:54 MEZ 1989 */
/* dieser Teil wurde von Peter Hain in Karlsruhe
entworfen. Er schrieb diese Langzahl arithmetik in Pascal und
Assembler. In Bayreuth wurden in Form eines Seminars die
Assemblerteile in C geschrieben und spaeter wurde von
Axel Kohnert die restlichen Pascalteile in C uebersetzt.
Die Ein und Ausgabe routinen wurden vollstaendig in Bayreuth
entworfen */

/* AK 130789 V1.0 *//* AK 250790 V1.1 */ /* AK 210891 V1.3 */
	{
	return ganzquores(x,rest,y);
	}
#endif /* LONGINTTRUE */

#ifdef LONGINTTRUE
static INT ganzein(fp,x) FILE *fp; struct longint *x; 
/* AK 130789 V1.0 *//* AK 250790 V1.1 */ /* AK 270391 V1.2 */
/* AK 210891 V1.3 */
	{
	INT i;
	signed char sgn=(signed char)1;
	char c;
	

	fscanf(fp,"%ld",&i);
	if (i <(INT)0) 
		{
		sgn = (signed char)-1;
		i = i *(INT)-1;
		}
	ganzint(x,  i % gd.basis);
	while ((c=getc(fp)) == (char) gd.folgezeichen)
		{
		fscanf(fp,"%ld",&i);
		if (i <(INT)0) 
			{
			return error("internal error LO14");
			}
		ganzsmul(x,gd.basis);
		ganzsadd(x,i % gd.basis);
		}

	x->signum = sgn;
	return OK;
	}
#endif /* LONGINTTRUE */


#ifdef LONGINTTRUE
static INT holeziffer(zd) struct zahldaten *zd;
/* AK 130789 V1.0 */ /* AK 050790 V1.1 */ /* AK 210891 V1.3 */
	{
	struct loc *adez;
	INT zzmod3,erg = OK;

	zd->ziffernzahl --;
	zzmod3 = zd->ziffernzahl % (INT)3;

	if (zzmod3 ==(INT)0) erg=zd->fdez->w0;
	if (zzmod3 ==(INT)1) erg=zd->fdez->w1;
	if (zzmod3 ==(INT)2) erg=zd->fdez->w2;

	if (zzmod3 ==(INT)0) 
		{ adez = zd->fdez; zd->fdez = zd->fdez->nloc;
		adez->nloc = NULL; locrette(&adez); }
	
	return(erg);
	}
#endif /* LONGINTTRUE */

#ifdef LONGINTTRUE
static INT ganzfziffer(zd) struct zahldaten *zd;
/* AK 130789 V1.0 */ /* AK 050790 V1.1 */ /* AK 210891 V1.3 */
	{
	INT z,f0;
	char buffer[200];

	if (zd->ziffernzahl == 0)
		{ zd->mehr = FALSE; strcpy(zd->ziffer," "); }
	else	{
		z = holeziffer(zd);
		if (zd->ziffernzahl > 0) zd->mehr=TRUE; else zd->mehr=FALSE;
		sprintf(buffer,"%ld",z);
		f0 = gd.basislaenge-strlen(buffer);
		sprintf(zd->ziffer,"%s","000000000000");
			/* max. 12 Nullen */
		sprintf(zd->ziffer + f0,"%ld",z);
		if (zd->mehr == TRUE)
			sprintf(zd->ziffer,"%s%c",
				zd->ziffer,gd.folgezeichen);
		else
			sprintf(zd->ziffer,"%s%c",zd->ziffer,' ');
		}
	return(OK);
	}
#endif /* LONGINTTRUE */

#ifdef LONGINTTRUE
static INT retteziffer(z,zd) INT	z; struct zahldaten *zd;
/* AK 130789 V1.0 */ /* AK 050790 V1.1 */ /* AK 210891 V1.3 */
	{
	struct loc *adez;
	INT zzmod3;

	zzmod3 = zd->ziffernzahl % (INT)3;

	if (zzmod3 ==(INT)0) {
		adez = NULL; lochole(&adez);
		adez ->nloc = zd->fdez; zd->fdez = adez; }
	if (zzmod3 ==(INT)0) zd->fdez->w0 = z;
	if (zzmod3 ==(INT)1) zd->fdez->w1 = z;
	if (zzmod3 ==(INT)2) zd->fdez->w2 = z;

	zd->ziffernzahl ++; 
	return(OK);
	}
#endif /* LONGINTTRUE */

#ifdef LONGINTTRUE
static INT ganz1ziffer(zd,x) struct zahldaten *zd; struct longint	*x;
/* AK 130789 V1.0 */ /* AK 030790 V1.1 */ /* AK 210891 V1.3 */
	{
	INT z;
	signed char sgn;
	struct longint xx;

	zd->fdez =  NULL; zd->ziffernzahl =(INT)0; xx.floc = NULL;
	(zd->ziffer)[0] = '\0';
	lochole(&xx.floc); ganzkopiere(&xx,x); sgn = xx.signum;
	if (xx.signum < (signed char)0) xx.signum = -xx.signum;

	while (xx.signum > (signed char)0)
		{ ganzsquores(&xx,&z,gd.basis); retteziffer(z,zd); }
	if (zd->ziffernzahl ==(INT)0)
		{ zd->mehr = FALSE; strcpy(zd->ziffer," "); }
	else	{
		z = holeziffer(zd); z = sgn * z;
		zd->mehr = (zd->ziffernzahl >(INT)0);
		if (zd->mehr == TRUE)
		  sprintf(zd->ziffer,"%s%ld%c",zd->ziffer,z,gd.folgezeichen);
		else	
		  sprintf(zd->ziffer,"%s%ld",zd->ziffer,z);
		}
	locrette(& xx.floc);
	return(OK);
	}
#endif /* LONGINTTRUE */

#ifdef LONGINTTRUE
static INT ganzaus_str(string,x) char *string; struct longint *x; 
/* AK 020295 */
	{
	struct zahldaten zd;
	int i,k;
	string[0]='\0';
	ganz1ziffer(&zd,x);
	k = strlen(zd.ziffer);
	if (zd.ziffer[k-1] == gd.folgezeichen)
		{
		zd.ziffer[k-1] = '\0';
		k--;
		}
	strcat(string,zd.ziffer);
	i = k;
	while (zd.mehr == TRUE)
		{
		ganzfziffer(&zd);
		k = strlen(zd.ziffer);
		if (zd.ziffer[k-1] == gd.folgezeichen)
			{
			zd.ziffer[k-1] = '\0';
			k--;
			}
		strcat(string,zd.ziffer);
		i+=k;
		}
	return OK;
	}

static INT ganzaus(fp,x) FILE *fp; struct longint *x; 
/* AK 130789 V1.0 */ /* AK 050790 V1.1 */ /* AK 210891 V1.3 */
	{
	struct zahldaten zd;
	char *blanks = (char *) SYM_calloc(201,sizeof(char));
	char *zeile  = (char *) SYM_calloc(201,sizeof(char));
	INT	i;

	for (i=1;i<gd.auspos;i++) blanks[i-1]=' ';
	blanks[(gd.auspos)-1]='\0';

	zd.ziffer[0] = '\0';

	zeile[0]='\0';
	gd.auszz = 0;

	ganz1ziffer(&zd,x);
	strcat(zeile,zd.ziffer);

	while (zd.mehr == TRUE)
		{
		ganzfziffer(&zd);
		if ((INT)strlen(zeile) + (INT)strlen(zd.ziffer) > gd.auslaenge)
			{ fprintf(fp,"%s%s\n",blanks,zeile);
			strcpy(zeile,zd.ziffer); gd.auszz++; }
		else	strcat(zeile,zd.ziffer);

		}
	
	if (fp == stdout) {
		zeilenposition  += strlen(zeile); 
		zeilenposition  += strlen(blanks);
		}
	else if (fp == texout)
		{
		texposition  += strlen(zeile); 
		texposition  += strlen(blanks);
		}

	fprintf(fp,"%s%s",blanks,zeile);
	if (fp == stdout)
		if (zeilenposition >(INT)70)
			{ fprintf(fp,"\n"); zeilenposition =(INT)0; }
	if (fp == texout)
		if (texposition >(INT)70)
			{ fprintf(fp,"\n"); texposition =(INT)0; }

		
	gd.auszz++; 
	SYM_free(blanks); 
	SYM_free(zeile); 
	return(OK);
	}
#endif /* LONGINTTRUE */

#ifdef LONGINTTRUE
static INT ganzmul(x,y) struct longint *x,*y;
/* AK Mon Jan 16 09:26:56 MEZ 1989 */
/* x = x * y */
/* AK 180789 V1.0 */ /* AK 080390 V1.1 */ /* AK 210891 V1.3 */
	{
	struct loc *alocx, *alocy,   *ploca, *floca, *bloca, *aloca;
	struct loc hi,lo,ov;
	INT	cy,cya;
	INT 	hh; /* fuer LOCADD,LOCMUL */



	x->signum = x->signum * y ->signum;
	if (x->signum == (signed char)0)
		{ 
		loclisterette(& (x->floc->nloc));
		locnull(x->floc); x->laenge =(INT)1; return OK;
		/* das ergebnis ist null */ }

	/* das ergebnis ist nicht null */
	x->laenge = x->laenge + y->laenge;
	floca = NULL; lochole(&floca); bloca = floca; alocx = x->floc->nloc;
	ploca = floca; aloca = NULL;
	while (alocx != NULL)
		{ lochole(&aloca); ploca->nloc = aloca;
		ploca = aloca; aloca = NULL; alocx = alocx->nloc; }

	alocy = y->floc;

	do	{
		cya =(INT)0; locnull(&ov); cy =(INT)0; alocx = x->floc; aloca = bloca;
		do	{ LOCMUL(&hi,&lo,alocx,alocy); 
			cy = LOCADD(&lo,&ov, cy);
			ov = hi; cya = LOCADD(aloca,&lo,cya);
			alocx=alocx->nloc; ploca=aloca; aloca = aloca->nloc; }
		while (alocx !=  NULL);
		cy = locsadd(&ov, cy+cya);
			/* cy ist jetzt 0 */
			if (cy !=(INT)0) 
				return error("internal error:LO2");
		lochole(&aloca);
		ploca->nloc = aloca;
		LOCASS(aloca,&ov);
		bloca = bloca->nloc;
		alocy = alocy->nloc;
		}
	while (alocy != NULL);

	if (locsgn(aloca ) ==(INT)0)
		{
		locrette(&(ploca->nloc));
		x->laenge --;
		}
	loclisterette(&x->floc);
	x->floc = floca;
	return OK;
	}
#endif /* LONGINTTRUE */

#ifdef LONGINTTRUE
static INT ganzsmul(x,a) struct longint *x; INT	a;
/* AK Mon Mar 13 10:08:51 MEZ 1989 */ /* AK 050790 V1.1 */
/* AK 210891 V1.3 */
{
	struct loc *alocx, *plocx;
	INT	ue;

if (a==(INT)0)
	{
	loclisterette(&(x->floc->nloc));
	x->signum = (signed char)locint(x->floc,(INT)0);
	x->laenge =(INT)1;
	}
else if (a ==(INT)1) ;
else if (a ==(INT)-1) x->signum = - x->signum;
else	{
	if (a<(INT)0) x->signum = - x->signum;
	alocx = x->floc; plocx = NULL; if (a<(INT)0) a = -a;
	ue =(INT)0;
	do	{ ue = locsmul(alocx,a,ue);
		plocx = alocx; alocx = alocx ->nloc; }
	while (alocx != NULL);
	if (ue !=(INT)0)
		{ lochole(&alocx); plocx->nloc = alocx; x->laenge ++;
		ue = locint(alocx,ue); }
	}
return OK;
}
#endif  /* LONGINTTRUE */


#ifdef LONGINTTRUE
static INT ganzsadd(x,y) struct longint *x; INT y; 
/* AK 180789 V1.0 */ /* AK 070390 V1.1 */ /* AK 210891 V1.3 */
	{
	INT cy,xl,ll;
	signed char xs,ys;
	struct loc *lloc,*alocx,*plocx;

	xl = x->laenge; 
	xs = x->signum;
	if (y>(INT)0) 
		ys=(signed char)1; 
	else if (y<(INT)0) 
		ys = (signed char)-1; 
	else 
		ys=(signed char)0;
	if (y<(INT)0) y = -y;

	if (	((xs>=(signed char)0)&&(ys>=(signed char)0))
		||
		((xs<(signed char)0)&&(ys < (signed char)0))
	   )
		{
		alocx = x->floc; 
		cy = y;
		while ((alocx != NULL)&&(cy !=(INT)0))
			{
			cy = locsadd(alocx,cy); 
			plocx = alocx;
			alocx = alocx->nloc;
			}
		if (cy !=(INT)0) 
			{
			lochole(&alocx); 
			plocx->nloc = alocx;
			locint(alocx,cy);
			xl ++;
			}
		if (xs == (signed char)0) 
			xs = ys;
		}
	else	{
		alocx = x->floc;
		cy = y;
		while ((alocx != NULL) && (cy !=(INT)0))
			{ 
			cy = locssub(alocx,cy);
			plocx = alocx; 
			alocx = alocx->nloc; 
			}
		if (cy !=(INT)0)
			{
			alocx = x->floc; 
			lloc = NULL; 
			ll = (INT) 1; 
			cy = (INT) 0;
			do	{ 
				cy = locneg(alocx,cy);
				if (locsgn(alocx) != (INT) 0 )
					{ lloc = alocx; xl = ll; }
				alocx = alocx->nloc;
				ll ++;
				}
			while (alocx != NULL);
			loclisterette(&(lloc->nloc));
			xs = -xs;
			if (xs == (signed char)0) 
				xs = (signed char)-1;
			}
		else 	{ 
			alocx = x->floc; 
			lloc = NULL; 
			ll = (INT)1;
			do	{
				if (locsgn(alocx) !=(INT)0)
					{ 
					lloc = alocx; 
					xl = ll; 
					}
				alocx = alocx->nloc;
				ll ++;
				}
			while (alocx != NULL);
			if (lloc == NULL)
				{
				loclisterette(&(x->floc->nloc));
				xs = (signed char)0; 
				xl = (INT)1;
				}
			else 	loclisterette(&(lloc->nloc));
			}
		}
	x->laenge = xl; 
	x->signum = xs;
	return(OK);
	}
#endif  /* LONGINTTRUE */
			


#ifdef LONGINTTRUE
static INT ganzvergleich(x,y) struct longint *x,*y;
/* AK Thu Jan 12 09:08:15 MEZ 1989 */
/* AK 130789 V1.0 */ /* AK 080390 V1.1 */ /* AK 210891 V1.3 */
	{
	struct loc *alocx, *alocy;
	INT	av,lv;
	signed char sx,sy;

	sx = x->signum; sy = y->signum;
	if (sx>sy) 
		return((INT)1);
	if (sx<sy) 
		return (INT) -1;
	/* es gilt nun gleiches vorzeichen */
	if (sx==(signed char)0) 
		return((INT)0);
	if (x->laenge > y->laenge) 
		return((INT)sx);
	if (x->laenge < y->laenge) 
		return((INT)-sy);
	/* es gilt nicht nur gleiches vorzeichen sondern auch
	gleiche laenge */
	alocx = x->floc;
	alocy = y->floc;
	lv = 0;
	do	{ av = locvgl(alocx,alocy);
		if (av != 0) lv = av;
		alocx = alocx->nloc; alocy = alocy->nloc; }
	while (alocx != NULL);
	if (sx>(signed char)0) 
		return(lv); 
	else 
		return(-lv);
	}
#endif /* LONGINTTRUE */

#ifdef LONGINTTRUE
static INT intganz(x) struct longint *x;
/* AK 150290 V1.1 */ /* umwandlung longint to int falls moeglich sonst fehler */
/* AK 210891 V1.3 */
	{
	INT wert;
	if (x->laenge != (INT)1) 
		return error("internal error:LO3");
		
	wert = x->floc->w0;
	wert += x->floc->w1 * LO_B;
	return( (INT)x->signum * wert );
	}
#endif /* LONGINTTRUE */

#ifdef LONGINTTRUE
static INT ganzint(x,i) struct longint *x; INT	i; 
/* AK Thu Jan 12 13:18:53 MEZ 1989 */
/* AK 130789 V1.0 */ /* AK 150290 V1.1 */ /* AK 210891 V1.3 */
	{
	if (x->floc->nloc != NULL) loclisterette(& x->floc->nloc );
	x->laenge = (INT)1;
	x->signum = (signed char)locint(x->floc,i);
	return(OK);
	}
#endif /* LONGINTTRUE */


#ifdef LONGINTTRUE
static INT ganzsignum(x) struct longint *x; 
/* AK 130789 V1.0 */ /* AK 050790 V1.1 */ /* AK 210891 V1.3 */
	{
	return (INT)x->signum;
	}
#endif /* LONGINTTRUE */

#ifdef LONGINTTRUE
static INT ganzeven(x) struct longint *x;
/* AK 061190 V1.1 */ /* AK 210891 V1.3 */
	{
	return not locodd(x->floc);
	}
#endif /* LONGINTTRUE */

#ifdef LONGINTTRUE
static INT ganzodd(x) struct longint *x;
/* AK 061190 V1.1 */ /* AK 210891 V1.3 */
	{
	return locodd(x->floc);
	}
#endif /* LONGINTTRUE */

#ifdef LONGINTTRUE
static INT ganzkopiere(x,a) struct longint *x,*a; 
/* x:= a AK umgeschrieben in C Fri Jan 20 07:46:34 MEZ 1989 */
/* AK 130789 V1.0 */ /* AK 050790 V1.1 */ /* AK 210891 V1.3 */
	{
	struct loc *alocx, *plocx, *aloca;

	if (x->floc == a->floc)
		 return error("internal error:LO4");

	x->signum = a->signum; x->laenge = a->laenge;
	aloca = a->floc; alocx = x->floc; plocx = NULL;

	do	{ if (alocx == NULL)
			{ lochole(&alocx); plocx->nloc = alocx; }
		LOCASS(alocx,aloca);
		aloca = aloca->nloc; plocx = alocx; alocx = alocx->nloc;
		}
	while (aloca != NULL);
	loclisterette(&(plocx->nloc));return(OK);
	}
#endif /* LONGINTTRUE */


#ifdef LONGINTTRUE
static INT ganzneg(x) struct longint *x;
/* AK 130789 V1.0 */ /* AK 201289 V1.1 */ /* AK 210891 V1.3 */
	{
	x->signum = -x->signum;return(OK);
	}
#endif /* LONGINTTRUE */


#ifdef LONGINTTRUE
static INT free_loc(a) struct loc *a;
{
	mem_counter_aloc--;
	SYM_free(a);
}

static INT lochole(aloc) struct loc   **aloc; 
/* AK 130789 V1.0 */ /* AK 080390 V1.1 */ /* AK 210891 V1.3 */
	{
	*aloc = (struct loc *) SYM_malloc(sizeof(struct loc));
	mem_counter_aloc++;
	if (*aloc == NULL) 
		return no_memory();
	locnull(*aloc);
	(*aloc)->nloc = NULL;
	return(OK);
	}
#endif /* LONGINTTRUE */

#ifdef LONGINTTRUE
static INT loclisterette(aloc) struct loc **aloc; 
/* AK 130789 V1.0 */ /* AK 010290 V1.1 */
/* AK 210891 V1.3 */
	{
	struct loc *aloc1, *ploc1;
	if (*aloc != NULL)
		{
		aloc1=   (*aloc);
		do { ploc1 = aloc1->nloc; FREE_LOC(aloc1); aloc1 = ploc1; }
		while 	(aloc1 != NULL);
		*aloc = NULL; 
		}
	return(OK);
	}
#endif /* LONGINTTRUE */


#ifdef LONGINTTRUE
static INT locrette(aloc) struct loc **aloc;
/* AK 130789 V1.0 */ /* AK 100190 V1.1 */ /* AK 210891 V1.3 */
	{
	if (*aloc != NULL)
		{
		FREE_LOC(*aloc);
		*aloc = NULL;
		}
	return(OK);
	}
#endif /* LONGINTTRUE */

#ifdef LONGINTTRUE
static INT locrezliste(aloc) struct loc **aloc;
/* AK Thu Jan 12 08:06:59 MEZ 1989 */
/* dreht liste um */
/* AK 100190 V1.1 */ /* AK 210891 V1.3 */
	{
	struct loc *lloc,*rloc,*hloc;
	if (*aloc != NULL)
		{
		lloc = NULL; rloc = *aloc;
		while (rloc != NULL)
			{
			hloc = rloc->nloc;
			rloc->nloc=lloc;
			lloc=rloc;
			rloc=hloc;
			}
		*aloc = lloc;
		}
	return(OK);
	}
#endif /* LONGINTTRUE */

#ifdef LONGINTTRUE
static INT schon_da =(INT)0;
INT start_longint()
/* AK 130789 V1.0 */ /* AK 050790 V1.1 */ /* AK 210891 V1.3 */
	{
	OP a,b;
	INT erg = OK;
	INT i;
	if (schon_da == (INT)1)
		{
		erg +=  error("start_longint: already initialised");
		goto endr_ende;
		}
	schon_da = (INT)1;
	rl_o=NULL; /* obere grenze */
	rl_m=NULL; /* modulo */
	rl_x=NULL; /* ergebnis */
	rl_a=NULL; /* multiplier */
	mem_counter_loc =(INT)0;
	mem_counter_aloc =(INT)0;
	erg += ganzanfang();
	erg += ganzparam((INT)1000000,(INT)2,(INT)70,'.');
	a = callocobject();
	b = callocobject();
	M_I_I((INT)1000,b);
	for (i=(INT)0;i<(INT)100;i++)
		{
		erg += random_integer(a,NULL,NULL);
		if (S_I_I(a) !=(INT)0)
			erg += mult_apply_integer(a,b);
		}
	erg += random_longint(a,b);
	erg += SYMfreeall(a);
	erg += SYMfreeall(b);
	ENDR("start_longint");
	}



INT longint_release()
{
	INT erg = OK;
	schon_da = 0;
	if (rl_o != NULL)
		erg += SYMfreeall(rl_o);
	if (rl_m != NULL)
		erg += SYMfreeall(rl_m);
	if (rl_a != NULL)
		erg += SYMfreeall(rl_a);
	if (rl_x != NULL)
		erg += SYMfreeall(rl_x);
	return erg;
}


INT longint_ende()
{
	INT erg = OK;
	if (mem_counter_aloc !=(INT)0)
		{
	fprintf(stderr,"longint memory not freed %ld\n",
			mem_counter_aloc);
		erg += ERROR;
		}
	if (mem_counter_loc !=(INT)0)
		{
		fprintf(stderr,"longint memory not freed %ld\n",
			mem_counter_loc);
		erg += ERROR;
		}
	return erg;
}

#endif /* LONGINTTRUE */

#ifdef LONGINTTRUE
static struct longint * calloclongint()
/* AK 170888 */ /* AK 130789 V1.0 */ /* AK 050790 V1.1 */
/* AK 210891 V1.3 */
	{
	struct longint *ergebnis = 
		(struct longint *) SYM_malloc( sizeof(struct longint));
	mem_counter_loc++;
	if (ergebnis == NULL) 
		return no_memory(),(struct longint *) NULL;
	return ergebnis;
	}
#endif /* LONGINTTRUE */


#ifdef LONGINTTRUE
static INT ganzparam(basis,auspos,auslaenge,folgezeichen) 
	INT basis,auspos,auslaenge;
	char	folgezeichen;
/* AK Mon Mar 13 10:24:35 MEZ 1989 */
/* AK 130789 V1.0 */ /* AK 080390 V1.1 */ /* AK 210891 V1.3 */
	{
	if (basis>(INT)1) gd.basis=basis; 
	else return error("internal error:LO5");

	if (auspos>(INT)1) gd.auspos=auspos; else gd.auspos = 2;
	if (basis <= (INT)10) gd.basislaenge = 1; else
	if (basis <= (INT)100) gd.basislaenge = 2; else
	if (basis <= (INT)1000) gd.basislaenge = 3; else
	if (basis <= (INT)10000) gd.basislaenge = 4; else
	if (basis <= (INT)100000) gd.basislaenge = 5; else
	if (basis <= (INT)1000000) gd.basislaenge = 6; else
	if (basis <= (INT)10000000) gd.basislaenge = 7; else
	if (basis <= (INT)100000000) gd.basislaenge = 8; else
	if (basis <= (INT)1000000000) gd.basislaenge = 9; else
				  gd.basislaenge = 10;
	if (auslaenge > gd.basislaenge) gd.auslaenge = auslaenge;
	else gd.auslaenge = gd.basislaenge+1;
	gd.folgezeichen = folgezeichen;return(OK);
	}
#endif /* LONGINTTRUE */

#ifdef LONGINTTRUE
static INT ganzanfang() 
/* AK: Tue Mar 14 08:43:55 MEZ 1989 */
/* dieser Teil wurde von Peter Hain in Karlsruhe
entworfen. Er schrieb diese Langzahl arithmetik in Pascal und
Assembler. In Bayreuth wurden in Form eines Seminars die
Assemblerteile in C geschrieben und spaeter wurde von
Axel Kohnert die restlichen Pascalteile in C uebersetzt.
Die Ein und Ausgabe routinen wurden vollstaendig in Bayreuth
entworfen */
/* AK 130789 V1.0 */ /* AK 080390 V1.1 */ /* AK 210891 V1.3 */
	{
	gd.auszz =(INT)0;
	gd.basis = (INT)1000000; gd.basislaenge = (INT)6; gd.folgezeichen = '.';
	gd.auspos =(INT)2; gd.auslaenge = (INT)78; return(OK);
	}
#endif /* LONGINTTRUE */

#ifdef LONGINTTRUE
static INT ganzdefiniere(x) struct longint *x;
/* AK: Tue Mar 14 08:47:54 MEZ 1989 */
/* dieser Teil wurde von Peter Hain in Karlsruhe
entworfen. Er schrieb diese Langzahl arithmetik in Pascal und
Assembler. In Bayreuth wurden in Form eines Seminars die
Assemblerteile in C geschrieben und spaeter wurde von
Axel Kohnert die restlichen Pascalteile in C uebersetzt.
Die Ein und Ausgabe routinen wurden vollstaendig in Bayreuth
entworfen */
/* AK 130789 V1.0 */ /* AK 080390 V1.1 */ /* AK 210891 V1.3 */
	{
	x->signum = (signed char)0; x->laenge = (INT)1; x->floc = NULL;
	lochole(&x->floc);
	return(OK);
	}
#endif /* LONGINTTRUE */

#ifdef LONGINTTRUE
static INT ganzloesche(x) struct longint *x;
/* AK: Tue Mar 14 08:49:35 MEZ 1989 */

/* dieser Teil wurde von Peter Hain in Karlsruhe
entworfen. Er schrieb diese Langzahl arithmetik in Pascal und
Assembler. In Bayreuth wurden in Form eines Seminars die
Assemblerteile in C geschrieben und spaeter wurde von
Axel Kohnert die restlichen Pascalteile in C uebersetzt.
Die Ein und Ausgabe routinen wurden vollstaendig in Bayreuth
entworfen */
/* AK 130789 V1.0 */ /* AK 080390 V1.1 */ /* AK 210891 V1.3 */
	{
	loclisterette(&x->floc);
	x->laenge =(INT)0; x->signum = (signed char)0;
	return(OK);
	}
#endif /* LONGINTTRUE */

#ifdef LONGINTTRUE
INT init_longint(l) OP l;
/* AK 170888 */ /* AK 130789 V1.0 */ /* AK 040790 V1.1 */
/* AK 210891 V1.3 */
	{
	OBJECTSELF c;

	c.ob_longint = calloclongint();
	B_KS_O(LONGINT,c,l);
	c = S_O_S(l);
	ganzdefiniere(c.ob_longint);
	return(OK);
	}
#endif /* LONGINTTRUE */

#ifdef LONGINTTRUE
INT sprint_longint(t,l) char *t; OP l;
/* AK 020295 */
	{
	INT erg=OK;
	OBJECTSELF c;
	c = S_O_S(l);
	erg += ganzaus_str(t, c.ob_longint);
	ENDR("sprint_longint");
	}

INT fprint_longint(f,l) FILE *f; OP l;
/* AK 130789 V1.0 */ /* AK 050790 V1.1 */ /* AK 210891 V1.3 */
	{
	INT erg = OK;
	OBJECTSELF c;

	if (nullp(l)) { /* AK 020889 V1.0 */
		erg += m_i_i((INT)0,l);
		erg += fprint_integer(f,l);
		goto fle;
		}
	c = S_O_S(l);
	erg += ganzaus(f, c.ob_longint);
fle:
	ENDR("fprint_longint");
	}





INT tex_longint(l) OP l;
/* AK 130789 V1.0 */ /* AK 050790 V1.1 */
/* AK 070291 V1.2 texout instaed of stdout for output */ /* AK 210891 V1.3 */
	{
	INT ts = texmath_yn;
	INT erg = OK;
	if (ts == 0L) fprintf(texout," $ "); else fprintf(texout," ");
	erg += fprint_longint(texout,l); 
	if (ts == 0L) fprintf(texout," $ "); else fprintf(texout," ");
	if (ts == 0L) texposition += (INT)6; else texposition += (INT)2;
	ENDR("tex_longint");
	}



INT copy_longint(a,c) OP a,c;
/* AK 180888 */ /* AK 130789 V1.0 */ /* AK 030790 V1.1 */
/* AK 210891 V1.3 */
	{
	OBJECTSELF cs,as;

	init(LONGINT,c);
	cs = S_O_S(c);
	as = S_O_S(a);
	return ganzkopiere(cs.ob_longint,as.ob_longint);
	/* erstes element wird gleich dem zweiten */
	}
#endif /* LONGINTTRUE */

#ifdef LONGINTTRUE
static INT free_longint(a) char *a;
{
	SYM_free(a);
}

INT freeself_longint(a) OP a;
/* AK 180888 */ /* AK 130789 V1.0 */ /* AK 030790 V1.1 */ /* AK 210891 V1.3 */
	{
	OBJECTSELF c;
	c = S_O_S(a);
	ganzloesche(c.ob_longint); 
	free_longint(c.ob_longint);
	mem_counter_loc--;
	return(OK);
	}
#endif /* LONGINTTRUE */


#ifdef LONGINTTRUE
INT add_longint(a,c,l) OP a,c,l;
/* AK 180888 */ /* AK 130789 V1.0 */ /* AK 050790 V1.1 */ /* AK 210891 V1.3 */
	{
	INT erg = OK;
	switch(S_O_K(c))
		{
#ifdef BRUCHTRUE
		case BRUCH: erg += add_bruch_scalar(c,a,l);
			if (S_O_K(l) == LONGINT)
				erg += t_longint_int(l);
			break;
#endif /* BRUCHTRUE */
		case INTEGER: erg += add_longint_integer(a,c,l);break;
		case LONGINT:{
			OBJECTSELF ls,cs;

			erg += copy(a,l);
			ls = S_O_S(l);
			cs = S_O_S(c);
			erg += ganzadd(ls.ob_longint,cs.ob_longint);
				/* longinteger-addition ist x:= x+y */
			erg += t_longint_int(l);
			break;
			}
		default:{
			erg += WTT("add_longint",a,c);
			break;
			}
		};
al_ende:
	ENDR("add_longint");
	}
#endif /* LONGINTTRUE */

#ifdef LONGINTTRUE
INT mult_longint(a,c,l) OP a,c,l;
/* AK 180888 */ /* AK 130789 V1.0 */ /* AK 050790 V1.1 */ /* AK 210891 V1.3 */
	{
	INT erg = OK;
	switch (S_O_K(c))
		{
#ifdef BRUCHTRUE
		case BRUCH: erg+=mult_bruch_integer(c,a,l);break;
#endif /* BRUCHTRUE */
#ifdef INTEGERTRUE
		case INTEGER: erg+=mult_longint_integer(a,c,l);break;
#endif /* INTEGERTRUE */
#ifdef MATRIXTRUE
		case MATRIX: erg+=mult_scalar_matrix(a,c,l);break;
#endif /* MATRIXTRUE */
#ifdef MONOMTRUE
		case MONOM: erg+=mult_scalar_monom(a,c,l);break;
#endif /* MONOMTRUE */
		case LONGINT: erg+=mult_longint_longint(a,c,l);break;
		case POLYNOM: erg+=mult_scalar_polynom(a,c,l);break;
#ifdef SCHURTRUE
		case SCHUR: erg+=mult_scalar_schur(a,c,l);break;
#endif /* SCHURTRUE */
#ifdef CHARTRUE
		case SYMCHAR: erg+=mult_scalar_symchar(a,c,l);break;
#endif /* CHARTRUE */
#ifdef VECTORTRUE
		case COMP:
		case WORD:
		case INTEGERVECTOR:
		case VECTOR: erg+=mult_scalar_vector(a,c,l);break;
#endif /* VECTORTRUE */
		default:
			{
			erg += WTT("mult_longint",a,c);
			break;
			}
		};
	ENDR("mult_longint");
	}
#endif /* LONGINTTRUE */

#ifdef LONGINTTRUE
INT mult_longint_longint(a,c,l) OP a ,c,l;
/* AK 310590 V1.1 */ /* AK 210891 V1.3 */
	{
	OBJECTSELF ls,cs;
	copy_longint(a,l);
	ls = S_O_S(l);
	cs = S_O_S(c);
	return ganzmul(ls.ob_longint,cs.ob_longint);
		/* longinteger-multiplikation ist x:= x*y */
	}
#endif /* LONGINTTRUE */
#ifdef LONGINTTRUE
INT absolute_longint(a,b) OP a,b;
/* AK 150393 */
{
	if (a==b)
		return ERROR;
	if (negp_longint(a))
		return addinvers(a,b);
	return copy(a,b);
}
#endif /* LONGINTTRUE */

#ifdef LONGINTTRUE
INT addinvers_apply_longint(a) OP a;
/* AK 201289 V1.1 */ /* AK 210891 V1.3 */
	{
	OBJECTSELF c;
	c = S_O_S(a);
	return(ganzneg(c.ob_longint));
	}
#endif /* LONGINTTRUE */

#ifdef LONGINTTRUE
INT addinvers_longint(a,l) OP a,l;
/* AK 180888 */ /* AK 130789 V1.0 */ /* AK 201289 V1.1 */ /* AK 210891 V1.3 */
	{
	OBJECTSELF c;

	copy(a,l);
	c = S_O_S(l);
	ganzneg(c.ob_longint);
		/* longinteger-addinvers ist x:= -x */
	return(OK);
	}
#endif /* LONGINTTRUE */


#ifdef LONGINTTRUE
INT add_apply_longint(a,b) OP a,b;
/* AK 120390 V1.1 */ /* AK 190291 V1.2 */ /* AK 210891 V1.3 */
	{
	INT erg = OK;
	switch (S_O_K(b)) {
#ifdef BRUCHTRUE
		case BRUCH: erg += add_apply_scalar_bruch(a,b); break;
#endif /* BRUCHTRUE */
		case INTEGER: erg += add_apply_longint_integer(a,b); break;
		case LONGINT: erg += add_apply_longint_longint(a,b); break;
		default: /* AK 190291 */
			{
			OP c = callocobject();
			*c = *b;
			C_O_K(b,EMPTY);
			erg += add(a,c,b);
			erg += SYMfreeall(c);
			}
		}
	if (erg != OK) {
		EDC("add_apply_longint");
		}
	return erg;
	}
#endif /* LONGINTTRUE */

#ifdef LONGINTTRUE
#ifdef MATRIXTRUE
INT mult_apply_longint_matrix(a,b) OP a,b;
/* AK 220390 V1.1 */ /* AK 190291 V1.2 */ /* AK 210891 V1.3 */
	{
	OP z = S_M_S(b);
	INT i = S_M_HI(b)*S_M_LI(b);
	INT erg=OK;
	for(;i>0;i--,z++)
		erg += mult_apply(a,z);
	ENDR("mult_apply_longint_matrix");
	}
#endif /* MATRIXTRUE */
#endif /* LONGINTTRUE */

#ifdef LONGINTTRUE
INT mult_apply_longint(a,b) OP a,b;
/* AK 080390 V1.1 */ /* AK 190291 V1.2 */ /* AK 210891 V1.3 */
	{
	INT erg = OK;
	switch (S_O_K(b)) {
#ifdef BRUCHTRUE
		case BRUCH: 
				erg += mult_apply_longint(a,S_B_O(b));
				C_B_I(b,NGEKUERZT); /* AK 010695 */
				erg += kuerzen(b); 
				break;
#endif /* BRUCHTRUE */
		case INTEGER: 
			erg += mult_apply_longint_integer(a,b);break;
		case LONGINT: 
			erg += mult_apply_longint_longint(a,b);break;
#ifdef MATRIXTRUE
		case MATRIX: 
			erg += mult_apply_longint_matrix(a,b);break;
#endif /* MATRIXTRUE */
		default: /* AK 190291 */
			{
			OP c = callocobject();
			INT erg=OK;
			*c = *b;
			C_O_K(b,EMPTY);
			erg += mult(a,c,b);
			erg += SYMfreeall(c);
			}
		}
	ENDR("mult_apply_longint");
	}
#endif /* LONGINTTRUE */

#ifdef LONGINTTRUE
INT add_apply_longint_longint(a,b) OP a,b;
/* AK 120390 V1.1 */ /* AK 050791 V1.3 */ /* AK 210891 V1.3 */
	{
	INT erg = OK;
	OBJECTSELF as,bs;
	as = S_O_S(a);
	bs = S_O_S(b);
	erg += ganzadd(bs.ob_longint,as.ob_longint);
	erg += t_longint_int(b);
	ENDR("add_apply_longint_longint");
	}
#endif /* LONGINTTRUE */

#ifdef LONGINTTRUE
INT mult_apply_longint_longint(a,b) OP a,b;
/* AK 080390 V1.1 */ /* AK 210891 V1.3 */
	{
	OBJECTSELF as,bs;
	as = S_O_S(a);
	bs = S_O_S(b);
	return(ganzmul(bs.ob_longint,as.ob_longint));
	}
#endif /* LONGINTTRUE */


#ifdef LONGINTTRUE
INT add_apply_longint_integer(a,b) OP a,b;
/* AK 120390 V1.1 */ /* AK 050791 V1.3 */
	{
	INT erg = OK;
	OP c = callocobject();
	*c = *b;
	C_O_K(b,EMPTY);
	erg += add(a,c,b);
	erg += SYMfreeall(c);
	erg += t_longint_int(b);
	return erg;
	}
#endif /* LONGINTTRUE */

#ifdef LONGINTTRUE
INT mult_apply_longint_integer(a,b) OP a,b;
/* AK 080390 V1.1 */ /* AK 050791 V1.3 */
	{
	OP c = callocobject();
	INT erg = OK;
	*c = *b;
	C_O_K(b,EMPTY);
	erg += mult(a,c,b);
	erg += SYMfreeall(c);
	return erg;
	}
#endif /* LONGINTTRUE */

#ifdef LONGINTTRUE
INT add_apply_integer_longint(a,b) OP a,b;
/* b = a + b */ /* b ist LONGINT, a ist INTEGER */
/* AK 120390 V1.1 */ /* AK 210891 V1.3 */
	{
	OBJECTSELF ls;
	ls = S_O_S(b);
	return(ganzsadd(ls.ob_longint,S_I_I(a)));
	}
#endif /* LONGINTTRUE */

#ifdef LONGINTTRUE
INT mult_apply_integer_longint(a,b) OP a,b;
/* b = a * b */ /* b ist LONGINT, a ist INTEGER */
/* AK 080290 V1.1 */ /* AK 210891 V1.3 */
	{
	OBJECTSELF ls;
	INT erg = OK;
	ls = S_O_S(b);
	erg += ganzsmul(ls.ob_longint,S_I_I(a));
	erg += t_longint_int(b);
	return erg;
	}
#endif /* LONGINTTRUE */

#ifdef LONGINTTRUE
INT mult_longint_integer(a,c,l) OP a,c,l;
/* a ist LONINT c ist INTEGER */ /* AK 180888 */
/* AK 130789 V1.0 */ /* AK 080290 V1.1 */ /* AK 210891 V1.3 */
	{
	INT erg = OK;
	OBJECTSELF ls;

	erg += copy_longint(a,l); ls = S_O_S(l);
	erg += ganzsmul(ls.ob_longint,S_I_I(c));
	erg += t_longint_int(l);
		/* longinteger-multiplikation ist x:= x*y */
	return erg;
	}
#endif /* LONGINTTRUE */

#ifdef LONGINTTRUE
INT add_longint_integer(a,c,l) OP a,c,l;
/* a is LONGINT c is INTEGER */ /* AK 180888 */
/* AK 130789 V1.0 */ /* AK 050790 V1.1 */ /* AK 210891 V1.3 */
	{
	OBJECTSELF ls;
	copy_longint(a,l);
	ls = S_O_S(l);
	ganzsadd(ls.ob_longint,S_I_I(c));
		/* longinteger-addition ist x:= x+y */
	t_longint_int(l);
	return(OK);
	}
#endif /* LONGINTTRUE */

#ifdef LONGINTTRUE
INT dec_longint(a) OP a;
/* AK 230888 */ /* AK 130789 V1.0 */ /* AK 050790 V1.1 */ /* AK 210891 V1.3 */
	{
	OBJECTSELF as ;
	as = S_O_S(a);
	ganzsadd(as.ob_longint,(INT)-1);
	return(OK);
	}
#endif /* LONGINTTRUE */

#ifdef LONGINTTRUE
INT inc_longint(a) OP a;
/* AK 230888 */ /* AK 130789 V1.0 */ /* AK 050790 V1.1 */ /* AK 210891 V1.3 */
	{
	OBJECTSELF as;
	as = S_O_S(a);

	return(ganzsadd(as.ob_longint,(INT)1));
	}
#endif /* LONGINTTRUE */

#ifdef LONGINTTRUE
INT t_longint_int(a) OP a;
/* AK 150290 V1.1 */ /* umwandlung in INTEGER falls moeglich */
/* AK 210891 V1.3 */
	{
	OBJECTSELF cs;
	INT wert;
	INT erg = OK;

	if (S_O_K(a) == INTEGER) 
		return OK;
	if (S_O_K(a) != LONGINT) 
		{
		erg += WTO("t_longint_int",a);
		goto tli_ende;
		}
	cs = S_O_S(a);
	if (cs.ob_longint ->laenge == (INT)1)
		if (cs.ob_longint ->floc ->w2 ==(INT)0)
		if (cs.ob_longint ->floc ->w1 < (INT)100)
		{
		wert = intganz(cs.ob_longint);
		erg += m_i_i(wert,a);
		goto tli_ende;
		}
tli_ende:
	ENDR("t_longint_int");
	}



INT einsp_longint(a) OP a;
/* AK 271190 V1.1 */ /* AK 250291 V1.2 */ /* AK 210891 V1.3 */
	{
	OBJECTSELF cs;
	cs = S_O_S(a);
	if (cs.ob_longint ->laenge == (INT)1)
	if (cs.ob_longint ->signum == (INT)1)
	if (cs.ob_longint ->floc ->w2 ==(INT)0)
	if (cs.ob_longint ->floc ->w1 ==(INT)0)
	if (cs.ob_longint ->floc ->w0 == (INT)1)
			return TRUE;
	return FALSE;
	}

INT t_int_longint(a,c) OP a,c;
/* umwandeln von INTEGER -> LONGINT AK 180888 */
/* AK 130789 V1.0 */ /* AK 150290 V1.1 */ /* AK 250391 V1.2 */
/* AK 210891 V1.3 */
	{
/* it is possible a == c */
	INT erg = OK;
	OBJECTSELF cs;
	INT av = S_I_I(a);

	erg += init(LONGINT,c); 
	cs = S_O_S(c);
	erg += ganzint(cs.ob_longint,av);
	ENDR("t_int_longint");
	}

INT comp_longint(a,c) OP a,c;
/* AK 180888 */ /* AK 130789 V1.0 */ /* AK 050790 V1.1 */ /* AK 210891 V1.3 */
	{
	OP d; 
	INT erg=OK;

	switch(S_O_K(c))
		{
		case INTEGER:
			{
			/* AK 190888 */
			OBJECTSELF as,ds;
			d = callocobject(); 
			t_int_longint(c,d); as=S_O_S(a); ds=S_O_S(d);
			erg = ganzvergleich(as.ob_longint, ds.ob_longint);
			SYMfreeall(d);
			return(erg);
			}
		case LONGINT:
			{
			OBJECTSELF as,cs;
			as=S_O_S(a); 
			cs=S_O_S(c);
			erg = ganzvergleich(as.ob_longint, cs.ob_longint);
			return(erg);
			}
#ifdef BRUCHTRUE
		case BRUCH:
			{
			d = callocobject(); 
			m_scalar_bruch(a,d);
			erg = comp(d,c);
			SYMfreeall(d);
			return erg;
			}
#endif /* BRUCHTRUE */
		default: {
			WTT("comp_longint",a,c);
			break;
			}
		};
	ENDR("comp_longint");
	}



INT check_longint(a) OP a;
/* AK 071294 */
/* test auf fuehrende Null */
{
	OBJECTSELF cs;
	struct loc *alocx, *plocx;
	if (S_O_K(a) != LONGINT) return OK;

	cs = S_O_S(a);
	alocx = (cs.ob_longint)->floc;
	while (alocx != NULL)
		{
		if (alocx -> nloc == NULL)
			{
			if ((alocx->w0 == 0) &&
			(alocx->w1 == 0) &&
			(alocx->w2 == 0) )

			error("internal error check_longint:");
			}
		alocx = alocx->nloc;
		}
	return OK;
}

INT half_apply_longint(a) OP a;
{
	OP d,e;
	OBJECTSELF cs;
	cs = S_O_S(a);
	ganzhalf(cs.ob_longint);
	return OK;
}

INT quores_longint(a,e,c,d) OP a,e,c,d;
/* ganzdiv AK 220888 */ /* c = a / e */
/* AK 130789 V1.0 */ /* AK 150290 V1.1 */ /* AK 210891 V1.3 */
	{
	INT erg = OK;
	switch (S_O_K(e))
		{
		case INTEGER:
			{
			OBJECTSELF cs;
			INT	rest;
			erg += copy(a,c);
			cs = S_O_S(c); 
			erg += ganzsquores(cs.ob_longint,&rest,S_I_I(e));
			erg += t_longint_int(c);
			erg += m_i_i(rest,d);
			goto ql_040393;
			}
		case LONGINT:
			{
			OBJECTSELF es,cs,ds;
			erg += copy(a,c); 
			erg += copy(c,d);
			cs = S_O_S(c); 
			es = S_O_S(e); 
			ds = S_O_S(d);
			erg += ganzquores(cs.ob_longint, 
				ds.ob_longint,es.ob_longint);
			erg += t_longint_int(c);
			erg += t_longint_int(d);
			goto ql_040393;
			}
		default: return WTT("quores_longint",a,e);
		};
ql_040393:
	if (negp(d))
		if (posp(e))
			{
			erg += add_apply(e,d);
			erg += dec(c);
			}
		else if (negp(e))
			{
			erg += sub(d,e,d);
			erg += inc(c);
			}
	ENDR("quores_longint");
	}
#endif /* LONGINTTRUE */


#ifdef LONGINTTRUE
INT scan_longint(a) OP a;
/* AK 180888 */ /* AK 130789 V1.0 */ /* AK 080390 V1.1 */ /* AK 210891 V1.3 */
	{
	OBJECTSELF as;
	
	printeingabe("longint:");
	init(LONGINT,a);as=S_O_S(a);
	ganzein(stdin,as.ob_longint);
	if (nullp(a) ) { /* AK 020889 V1.0 */
		m_i_i((INT)0,a); 
		}
	return(OK);
	}
#endif /* LONGINTTRUE */

#ifdef LONGINTTRUE
INT posp_longint(a) OP a;
/* AK 190888 */ /* AK 280689 V1.0 */ /* AK 080390 V1.1 */ /* AK 210891 V1.3 */
	{
	OBJECTSELF as;
	as=S_O_S(a);
	return  GANZSIGNUM(as.ob_longint) == (INT)1;
	}
#endif /* LONGINTTRUE */

#ifdef LONGINTTRUE
INT odd_longint(a) OP a;
/* AK 061190 V1.1 */ /* AK 210891 V1.3 */
	{
	OBJECTSELF as;
	as=S_O_S(a);
	return ganzodd(as.ob_longint);
	}
#endif /* LONGINTTRUE */

#ifdef LONGINTTRUE
INT even_longint(a) OP a;
/* AK 061190 V1.1 */ /* AK 210891 V1.3 */
	{
	OBJECTSELF as;
	as=S_O_S(a);
	return ganzeven(as.ob_longint);
	}
#endif /* LONGINTTRUE */

#ifdef LONGINTTRUE
INT nullp_longint(a) OP a;
/* AK 190888 */ /* AK 280689 V1.0 */ /* AK 080390 V1.1 */ /* AK 210891 V1.3 */
	{
	OBJECTSELF as;
	as=S_O_S(a);
	return(ganzsignum(as.ob_longint) ==(INT)0);
	}
#endif /* LONGINTTRUE */


#ifdef LONGINTTRUE
INT negp_longint(a) OP a;
/* AK 190888 */ /* AK 130789 V1.0 */ /* AK 080390 V1.1 */ /* AK 210891 V1.3 */
	{
	OBJECTSELF as;
	as=S_O_S(a);
	return(ganzsignum(as.ob_longint) == -1);
	}
#endif /* LONGINTTRUE */

#ifdef LONGINTTRUE
INT objectread_longint(f,l) FILE *f; OP l;
/* AK 130789 V1.0 */ /* AK 080390 V1.1 */ /* AK 210891 V1.3 */
	{
	OBJECTSELF ls;

	init(LONGINT,l);
	ls=S_O_S(l);
	ganzein(f, ls.ob_longint);
	return(OK);
	}
#endif /* LONGINTTRUE */

#ifdef LONGINTTRUE
INT objectwrite_longint(f,l) FILE *f; OP l;
/* AK 130789 V1.0 */ /* AK 080390 V1.1 */ /* AK 210891 V1.3 */
	{
	INT erg = OK;
	OBJECTSELF ls;

	if (nullp(l)) { /* AK 020889 V1.0 */
		erg += m_i_i((INT)0,l);
		erg += objectwrite_integer(f,l);
		goto owlende;
		}

	fprintf(f," %d ",LONGINT);
	ls=S_O_S(l);
	erg += ganzaus(f, ls.ob_longint); 
	fprintf(f,"\n"); 
owlende:
	ENDR("objectwrite_longint");
	}



INT m_i_longint(a,b) OP b;INT a;
/* AK 180888 */ /* AK 270689 V1.0 */ /* AK 080390 V1.1 */ /* AK 210891 V1.3 */
	{
	OP c = callocobject(); 
	INT erg = OK;
	erg += m_i_i(a,c);		/* make INT --> INTEGER */
	erg += t_int_longint(c,b); /* transform INTEGER --> LONGINT */
	erg += SYMfreeall(c); 
	ENDR("m_i_longint");
	}
#endif /* LONGINTTRUE */

#ifdef LONGINTTRUE
INT debugprint_longint(a) OP a;
/* AK 020390 V1.1 */ /* AK 210891 V1.3 */
{
	OBJECTSELF c;
	INT k;
	struct loc *alocx, *plocx;
	c = s_o_s(a);
	for (k=0L;k<doffset;k++) fprintf(stderr," ");
	fprintf(stderr,"kind:22=longint\n");
	for (k=0L;k<doffset;k++) fprintf(stderr," ");
	fprintf(stderr,"laenge = %ld\n",
	    c.ob_longint->laenge);
	for (k=0L;k<doffset;k++) fprintf(stderr," ");
	fprintf(stderr,"signum = %d\n",
	    c.ob_longint->signum);
	alocx = c.ob_longint->floc; /* AK 071294 */
	while (alocx != NULL)
		{
		for (k=0L;k<doffset;k++) fprintf(stderr," ");
		fprintf(stderr,"%ld %ld %ld\n",alocx->w0,alocx->w1,alocx->w2);
		alocx= alocx->nloc;
		}
	return(OK);
}

INT sscan_longint(t,a) char *t; OP a;
{
	INT erg = OK;
	INT vz=(INT)1;
	char c;
	OP zehn, faktor;
	zehn = callocobject(); 
	M_I_I((INT)10,zehn);
	faktor = callocobject();
	m_i_i((INT)0,a);
slagain:
	c = *t++;
	if (c == '\0') 
		{
		erg = ERROR;
		goto sle;
		}
	if (c == ' ')
		goto slagain;
	if (c == '-')
		{
		if (vz == (INT)-1) { erg = ERROR; goto sle; }
		vz = (INT)-1;
		goto slagain;
		}
	if (not SYM_isdigit(c))
		{
		erg = ERROR;
		goto sle;
		}	
slb:
	erg += mult_apply(zehn,a);
	erg += m_i_i((INT)9-('9'-c),faktor);
	erg += add_apply(faktor,a);
	c = *t++;
	if (c == '\0') 
		{
		goto sle;
		}
	if (not SYM_isdigit(c))
		{
		erg = ERROR;
		goto sle;
		}	
	goto slb;
sle:
	erg += SYMfreeall(zehn);
	erg += SYMfreeall(faktor);
	if (vz == (INT)-1) 
		erg += addinvers_apply(a);
	ENDR("sscan_longint");
}

#endif /* LONGINTTRUE */

#ifdef LONGINTTRUE
INT test_longint() {
/* AK 020390 V1.1 */ /* AK 210891 V1.3 */
	OP a = callocobject();
	OP b = callocobject();
	OP c = callocobject();

	start_longint();
	printf("test_longint:scan(a)"); scan(LONGINT,a);println(a);
	printf("test_longint:add(a,a,b)"); add(a,a,b); println(b);
	printf("test_longint:mult(a,b,b)"); mult(a,b,b); println(b);
	printf("test_longint:m_i_i((INT)-1,c);mult(c,b,b)");
	m_i_i((INT)-1,c); mult(c,b,b); println(b);
	printf("test_longint:m_i_i((INT)-1,c);add(c,b,b)");
	m_i_i((INT)-1,c); add(c,b,b); println(b);
#ifdef BRUCHTRUE
	printf("test_longint:invers(b,a)"); invers(b,a); println(a);
#endif /* BRUCHTRUE */
	printf("test_longint:mult(b,a,a)"); mult(b,a,a); println(a);

	printf("test_longint:m_i_i((INT)3,c);div3(a,c,b)");
	m_i_i((INT)3,c); div3(a,c,b); println(b);
	printf("test_longint:m_i_i((INT)100,c);fakul(c,b)");
	m_i_i((INT)100,c); fakul(c,b); println(b);

	SYMfreeall(a);SYMfreeall(b);SYMfreeall(c);
	return(OK);
	}
	
INT random_longint(res,ober) OP res,ober;
/* AK 080390 V1.1 */
/* ober ist beim ersten aufruf die obere grenze, spater NULL */
/* AK 210891 V1.3 */
	{
	INT l,i;
	INT erg = OK; /* AK 030893 */
	OP h1,h2,h3;
rla:
	if (ober == NULL) {
		if (rl_o == NULL) return(
				error("random_longint: no initialisation"));
		}
	else	{
		if (rl_o == NULL) {
			rl_o=callocobject(); 
			rl_a=callocobject();
			rl_x=callocobject(); 
			rl_m=callocobject();
			}
		else 	{
			erg += freeself(rl_o); 
			erg += freeself(rl_a); 
			erg += freeself(rl_x); 
			erg += freeself(rl_m);
			}
		erg += copy(ober,rl_o);
		h1 = callocobject(); 
		h2 = callocobject();
		h3 = callocobject();
		l = (S_O_S(ober).ob_longint->laenge) * 3 ; /* laenge */
		erg += m_i_i((INT)10,rl_m);
		erg += m_i_i(l*(INT)6,h1);
		erg += hoch(rl_m,h1,rl_m);
		erg += m_i_i((INT)222222,rl_a);
		erg += m_i_i((INT)1000000,h2);
		erg += m_i_i((INT)222222,h1);
		erg += m_i_i((INT)0,rl_x);
		for (i=1;i<=l;i++)
			{
			erg += mult_apply(h2,rl_a);
			erg += add_apply(h1,rl_a);
			erg += random_integer(h3,NULL,h2);
			erg += mult_apply(h2,rl_x);
			erg += add_apply(h3,rl_x);
			}
		erg += mod(rl_x,rl_o,res); 
		erg += SYMfreeall(h1); 
		erg += SYMfreeall(h2); 
		erg += SYMfreeall(h3);
		goto rl_ende;
		}
	/* dies ist der fall dass initialisiert ist */
	h1 = callocobject();
	erg += mult(rl_x,rl_a,h1);
	erg += mod(h1,rl_m,rl_x);
	erg += mod(rl_x,rl_o,res); 
	erg += SYMfreeall(h1);
rl_ende:
	ENDR("random_longint");
	}

#endif /* LONGINTTRUE */
