1: #include "lint.h" 2: #ifndef lint 3: static char sccs_id[] = "@(#)madd.c 2.1 7/6/82"; 4: #endif lint 5: 6: #include <ape.h> 7: m_add(a,b,c) 8: MINT *a,*b,*c; /* c = a + b for a->len >= b->len >= 0 */ 9: { int carry,i; 10: int x; 11: short *cval; /* just used for convenience */ 12: 13: cval=xalloc(a->len+1,"m_add"); 14: carry=0; 15: for(i=0;i<b->len;i++) /* do addition, propagating carries */ 16: { x=carry+a->val[i]+b->val[i]; 17: if(x&CARRYBIT) 18: { carry=1; 19: cval[i]=x&TOPSHORT; 20: } 21: else 22: { carry=0; 23: cval[i]=x; 24: } 25: } 26: for(;i<a->len;i++) /* propagate carries the rest of the way */ 27: { x=carry+a->val[i]; 28: if(x&CARRYBIT) cval[i]=x&TOPSHORT; 29: else 30: { carry=0; 31: cval[i]=x; 32: } 33: 34: } 35: if(carry==1) 36: { cval[i]=1; 37: c->len=i+1; 38: } 39: else c->len=a->len; 40: c->val=cval; 41: if(c->len==0) shfree(cval); 42: return; 43: } 44: 45: madd(a,b,c) /* c = a + b; keeps track of sign, etc. */ 46: MINT *a,*b,*c; 47: { MINT x,y,z; 48: int sign; 49: 50: x.len=a->len; 51: x.val=a->val; 52: y.len=b->len; 53: y.val=b->val; 54: z.len=0; 55: sign=1; 56: if(x.len>=0) 57: if(y.len>=0) 58: if(x.len>=y.len) m_add(&x,&y,&z); 59: else m_add(&y,&x,&z); 60: else 61: { y.len= -y.len; 62: msub(&x,&y,&z); 63: } 64: else if(y.len<=0) 65: { x.len = -x.len; 66: y.len= -y.len; 67: sign= -1; 68: madd(&x,&y,&z); 69: } 70: else 71: { x.len= -x.len; 72: msub(&y,&x,&z); 73: } 74: xfree(c); 75: c->val=z.val; 76: c->len=sign*z.len; 77: return; 78: } 79: 80: m_sub(a,b,c) 81: MINT *a,*b,*c; /* c = a - b for a->len >= b->len >= 0 */ 82: { int x,i; 83: int borrow; 84: 85: c->val=xalloc(a->len,"m_sub"); 86: borrow=0; 87: for(i=0;i<b->len;i++) /* do subtraction, propagating borrows */ 88: { x=borrow+a->val[i]-b->val[i]; 89: if(x&CARRYBIT) 90: { borrow= -1; 91: c->val[i]=x&TOPSHORT; 92: } 93: else 94: { borrow=0; 95: c->val[i]=x; 96: } 97: } 98: for(;i<a->len;i++) /* propagate borrows the rest of the way */ 99: { x=borrow+a->val[i]; 100: if(x&CARRYBIT) c->val[i]=x&TOPSHORT; 101: else 102: { borrow=0; 103: c->val[i]=x; 104: } 105: } 106: /* if a borrow is left over (b>a) we have to take the 2's 107: * complement by flipping c's bits and adding one 108: */ 109: if (borrow<0) 110: { 111: short one; 112: MINT mone; 113: 114: one=1; mone.len= 1; mone.val= &one; /* simple conversion */ 115: for(i=0;i<a->len;i++) c->val[i] ^= TOPSHORT; 116: c->len=a->len; 117: madd(c,&mone,c); 118: } 119: for (i=a->len-1;i>=0;--i) 120: if(c->val[i]>0) /* determine c's length by finding last non- 121: * zero word */ 122: { if(borrow==0) c->len=i+1; 123: else c->len= -i-1; 124: return; 125: } 126: shfree(c->val); /* Can only get here if the result is zero */ 127: return; 128: } 129: 130: msub(a,b,c) 131: MINT *a,*b,*c; /* c = a - b; keeps signs straight, etc. */ 132: { MINT x,y,z; 133: int sign; 134: 135: x.len=a->len; 136: y.len=b->len; 137: x.val=a->val; 138: y.val=b->val; 139: z.len=0; 140: sign=1; 141: if(x.len>=0) 142: if(y.len>=0) 143: if(x.len>=y.len) m_sub(&x,&y,&z); 144: else 145: { sign= -1; 146: msub(&y,&x,&z); 147: } 148: else 149: { y.len= -y.len; 150: madd(&x,&y,&z); 151: } 152: else if(y.len<=0) 153: { sign= -1; 154: x.len= -x.len; 155: y.len= -y.len; 156: msub(&y,&x,&z); 157: } 158: else 159: { x.len= -x.len; 160: madd(&x,&y,&z); 161: sign= -1; 162: } 163: xfree(c); 164: c->val=z.val; 165: c->len=sign*z.len; 166: return; 167: }