1 typedef unsigned long ulong;
2 typedef unsigned int uint;
3 typedef unsigned short ushort;
4 typedef unsigned char uchar;
5 typedef signed char schar;
7 #define SIGN(n) (1UL<<(n-1))
9 typedef struct Vlong Vlong;
31 void _subv(Vlong*, Vlong, Vlong);
34 _d2v(Vlong *y, double d)
36 union { double d; struct Vlong; } x;
37 ulong xhi, xlo, ylo, yhi;
42 xhi = (x.hi & 0xfffff) | 0x100000;
44 sh = 1075 - ((x.hi >> 20) & 0x7ff);
49 /* v = (hi||lo) >> sh */
55 ylo = (xlo >> sh) | (xhi << (32-sh));
67 /* v = (hi||lo) << -sh */
71 yhi = (xhi << sh) | (xlo >> (32-sh));
74 yhi = d; /* causes something awful */
90 _f2v(Vlong *y, float f)
104 return -((long)x.hi*4294967296. + x.lo);
106 return (long)x.hi*4294967296. + x.lo;
118 return x.hi*4294967296. + x.lo;
128 _vasaddd(Vlong *ret, Vlong *lv, double v2d(Vlong), double rv)
130 _d2v(lv, v2d(*lv)+rv);
134 _vassubd(Vlong *ret, Vlong *lv, double v2d(Vlong), double rv)
136 _d2v(lv, v2d(*lv)-rv);
140 _vasmuld(Vlong *ret, Vlong *lv, double v2d(Vlong), double rv)
142 _d2v(lv, v2d(*lv)*rv);
146 _vasdivd(Vlong *ret, Vlong *lv, double v2d(Vlong), double rv)
148 _d2v(lv, v2d(*lv)/rv);
152 ulong _div64by32(Vlong, ulong, ulong*);
153 void _mul64by32(Vlong*, Vlong, ulong);
156 slowdodiv(Vlong num, Vlong den, Vlong *q, Vlong *r)
158 ulong numlo, numhi, denhi, denlo, quohi, quolo, t;
167 * get a divide by zero
169 if(denlo==0 && denhi==0) {
170 numlo = numlo / denlo;
174 * set up the divisor and find the number of iterations needed
176 if(numhi >= SIGN(32)) {
184 while(denhi < quohi || (denhi == quohi && denlo < quolo)) {
185 denhi = (denhi<<1) | (denlo>>31);
193 quohi = (quohi<<1) | (quolo>>31);
195 if(numhi > denhi || (numhi == denhi && numlo >= denlo)) {
203 denlo = (denlo>>1) | (denhi<<31);
218 dodiv(Vlong num, Vlong den, Vlong *qp, Vlong *rp)
223 if(den.hi > num.hi || (den.hi == num.hi && den.lo > num.lo)){
238 _mul64by32(&x, den, n);
239 if(x.hi > num.hi || (x.hi == num.hi && x.lo > num.lo))
240 slowdodiv(num, den, &q, &r);
246 if(num.hi >= den.lo){
247 q.hi = n = num.hi/den.lo;
252 q.lo = _div64by32(num, den.lo, &r.lo);
266 _divvu(Vlong *q, Vlong n, Vlong d)
269 if(n.hi == 0 && d.hi == 0) {
278 _modvu(Vlong *r, Vlong n, Vlong d)
281 if(n.hi == 0 && d.hi == 0) {
302 _divv(Vlong *q, Vlong n, Vlong d)
306 if(n.hi == (((long)n.lo)>>31) && d.hi == (((long)d.lo)>>31)) {
307 q->lo = (long)n.lo / (long)d.lo;
308 q->hi = ((long)q->lo) >> 31;
323 _modv(Vlong *r, Vlong n, Vlong d)
327 if(n.hi == (((long)n.lo)>>31) && d.hi == (((long)d.lo)>>31)) {
328 r->lo = (long)n.lo % (long)d.lo;
329 r->hi = ((long)r->lo) >> 31;
344 _rshav(Vlong *r, Vlong a, int b)
352 /* this is illegal re C standard */
365 r->lo = (t << (32-b)) | (a.lo >> b);
369 _rshlv(Vlong *r, Vlong a, int b)
377 /* this is illegal re C standard */
390 r->lo = (t << (32-b)) | (a.lo >> b);
394 _lshv(Vlong *r, Vlong a, int b)
402 /* this is illegal re C standard */
415 r->hi = (t >> (32-b)) | (a.hi << b);
419 _andv(Vlong *r, Vlong a, Vlong b)
426 _orv(Vlong *r, Vlong a, Vlong b)
433 _xorv(Vlong *r, Vlong a, Vlong b)
440 _vpp(Vlong *l, Vlong *r)
451 _vmm(Vlong *l, Vlong *r)
462 _ppv(Vlong *l, Vlong *r)
473 _mmv(Vlong *l, Vlong *r)
484 _vasop(Vlong *ret, void *lv, void fn(Vlong*, Vlong, Vlong), int type, Vlong rv)
553 fn(&u, *(Vlong*)lv, rv);
561 _p2v(Vlong *ret, void *p)
571 _sl2v(Vlong *ret, long sl)
581 _ul2v(Vlong *ret, ulong ul)
591 _si2v(Vlong *ret, int si)
601 _ui2v(Vlong *ret, uint ui)
611 _sh2v(Vlong *ret, long sh)
615 t = (sh << 16) >> 16;
621 _uh2v(Vlong *ret, ulong ul)
631 _sc2v(Vlong *ret, long uc)
635 t = (uc << 24) >> 24;
641 _uc2v(Vlong *ret, ulong ul)
656 return (t << 24) >> 24;
672 return (t << 16) >> 16;
679 return rv.lo & 0xffff;
713 return rv.lo || rv.hi;
717 _eqv(Vlong lv, Vlong rv)
719 return lv.lo == rv.lo && lv.hi == rv.hi;
723 _nev(Vlong lv, Vlong rv)
725 return lv.lo != rv.lo || lv.hi != rv.hi;
729 _ltv(Vlong lv, Vlong rv)
731 return (long)lv.hi < (long)rv.hi ||
732 (lv.hi == rv.hi && lv.lo < rv.lo);
736 _lev(Vlong lv, Vlong rv)
738 return (long)lv.hi < (long)rv.hi ||
739 (lv.hi == rv.hi && lv.lo <= rv.lo);
743 _gtv(Vlong lv, Vlong rv)
745 return (long)lv.hi > (long)rv.hi ||
746 (lv.hi == rv.hi && lv.lo > rv.lo);
750 _gev(Vlong lv, Vlong rv)
752 return (long)lv.hi > (long)rv.hi ||
753 (lv.hi == rv.hi && lv.lo >= rv.lo);
757 _lov(Vlong lv, Vlong rv)
759 return lv.hi < rv.hi ||
760 (lv.hi == rv.hi && lv.lo < rv.lo);
764 _lsv(Vlong lv, Vlong rv)
766 return lv.hi < rv.hi ||
767 (lv.hi == rv.hi && lv.lo <= rv.lo);
771 _hiv(Vlong lv, Vlong rv)
773 return lv.hi > rv.hi ||
774 (lv.hi == rv.hi && lv.lo > rv.lo);
778 _hsv(Vlong lv, Vlong rv)
780 return lv.hi > rv.hi ||
781 (lv.hi == rv.hi && lv.lo >= rv.lo);