148370Sbostic /*- 248370Sbostic * %sccs.include.proprietary.c% 348370Sbostic */ 448370Sbostic 519819Sdist #ifndef lint 6*61321Sbostic static char sccsid[] = "@(#)madd.c 8.1 (Berkeley) 06/04/93"; 748370Sbostic #endif /* not lint */ 819819Sdist 99945Ssam #include <mp.h> 109945Ssam m_add(a,b,c) struct mint *a,*b,*c; 119945Ssam { int carry,i; 129945Ssam int x; 139945Ssam short *cval; 149945Ssam cval=xalloc(a->len+1,"m_add"); 159945Ssam carry=0; 169945Ssam for(i=0;i<b->len;i++) 179945Ssam { x=carry+a->val[i]+b->val[i]; 189945Ssam if(x&0100000) 199945Ssam { carry=1; 209945Ssam cval[i]=x&077777; 219945Ssam } 229945Ssam else 239945Ssam { carry=0; 249945Ssam cval[i]=x; 259945Ssam } 269945Ssam } 279945Ssam for(;i<a->len;i++) 289945Ssam { x=carry+a->val[i]; 299945Ssam if(x&0100000) cval[i]=x&077777; 309945Ssam else 319945Ssam { carry=0; 329945Ssam cval[i]=x; 339945Ssam } 349945Ssam 359945Ssam } 369945Ssam if(carry==1) 379945Ssam { cval[i]=1; 389945Ssam c->len=i+1; 399945Ssam } 409945Ssam else c->len=a->len; 419945Ssam c->val=cval; 429945Ssam if(c->len==0) shfree(cval); 439945Ssam return; 449945Ssam } 459945Ssam madd(a,b,c) struct mint *a,*b,*c; 469945Ssam { struct mint x,y,z; 479945Ssam int sign; 489945Ssam x.len=a->len; 499945Ssam x.val=a->val; 509945Ssam y.len=b->len; 519945Ssam y.val=b->val; 529945Ssam z.len=0; 539945Ssam sign=1; 549945Ssam if(x.len>=0) 559945Ssam if(y.len>=0) 569945Ssam if(x.len>=y.len) m_add(&x,&y,&z); 579945Ssam else m_add(&y,&x,&z); 589945Ssam else 599945Ssam { y.len= -y.len; 609945Ssam msub(&x,&y,&z); 619945Ssam } 629945Ssam else if(y.len<=0) 639945Ssam { x.len = -x.len; 649945Ssam y.len= -y.len; 659945Ssam sign= -1; 669945Ssam madd(&x,&y,&z); 679945Ssam } 689945Ssam else 699945Ssam { x.len= -x.len; 709945Ssam msub(&y,&x,&z); 719945Ssam } 729945Ssam xfree(c); 739945Ssam c->val=z.val; 749945Ssam c->len=sign*z.len; 759945Ssam return; 769945Ssam } 779945Ssam m_sub(a,b,c) struct mint *a,*b,*c; 789945Ssam { int x,i; 799945Ssam int borrow; 809945Ssam short one; 819945Ssam struct mint mone; 829945Ssam one=1; mone.len= 1; mone.val= &one; 839945Ssam c->val=xalloc(a->len,"m_sub"); 849945Ssam borrow=0; 859945Ssam for(i=0;i<b->len;i++) 869945Ssam { x=borrow+a->val[i]-b->val[i]; 879945Ssam if(x&0100000) 889945Ssam { borrow= -1; 899945Ssam c->val[i]=x&077777; 909945Ssam } 919945Ssam else 929945Ssam { borrow=0; 939945Ssam c->val[i]=x; 949945Ssam } 959945Ssam } 969945Ssam for(;i<a->len;i++) 979945Ssam { x=borrow+a->val[i]; 989945Ssam if(x&0100000) c->val[i]=x&077777; 999945Ssam else 1009945Ssam { borrow=0; 1019945Ssam c->val[i]=x; 1029945Ssam } 1039945Ssam } 1049945Ssam if(borrow<0) 1059945Ssam { for(i=0;i<a->len;i++) c->val[i] ^= 077777; 1069945Ssam c->len=a->len; 1079945Ssam madd(c,&mone,c); 1089945Ssam } 1099945Ssam for(i=a->len-1;i>=0;--i) if(c->val[i]>0) 1109945Ssam { if(borrow==0) c->len=i+1; 1119945Ssam else c->len= -i-1; 1129945Ssam return; 1139945Ssam } 1149945Ssam shfree(c->val); 1159945Ssam return; 1169945Ssam } 1179945Ssam msub(a,b,c) struct mint *a,*b,*c; 1189945Ssam { struct mint x,y,z; 1199945Ssam int sign; 1209945Ssam x.len=a->len; 1219945Ssam y.len=b->len; 1229945Ssam x.val=a->val; 1239945Ssam y.val=b->val; 1249945Ssam z.len=0; 1259945Ssam sign=1; 1269945Ssam if(x.len>=0) 1279945Ssam if(y.len>=0) 1289945Ssam if(x.len>=y.len) m_sub(&x,&y,&z); 1299945Ssam else 1309945Ssam { sign= -1; 1319945Ssam msub(&y,&x,&z); 1329945Ssam } 1339945Ssam else 1349945Ssam { y.len= -y.len; 1359945Ssam madd(&x,&y,&z); 1369945Ssam } 1379945Ssam else if(y.len<=0) 1389945Ssam { sign= -1; 1399945Ssam x.len= -x.len; 1409945Ssam y.len= -y.len; 1419945Ssam msub(&y,&x,&z); 1429945Ssam } 1439945Ssam else 1449945Ssam { x.len= -x.len; 1459945Ssam madd(&x,&y,&z); 1469945Ssam sign= -1; 1479945Ssam } 1489945Ssam if(a==c && x.len!=0) xfree(a); 1499945Ssam else if(b==c && y.len!=0) xfree(b); 1509945Ssam else xfree(c); 1519945Ssam c->val=z.val; 1529945Ssam c->len=sign*z.len; 1539945Ssam return; 1549945Ssam } 155