plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

mptov.c (1254B)


      1 #include "os.h"
      2 #include <mp.h>
      3 #include "dat.h"
      4 
      5 #define VLDIGITS (sizeof(vlong)/sizeof(mpdigit))
      6 
      7 /*
      8  *  this code assumes that a vlong is an integral number of
      9  *  mpdigits long.
     10  */
     11 mpint*
     12 vtomp(vlong v, mpint *b)
     13 {
     14 	int s;
     15 	uvlong uv;
     16 
     17 	if(b == nil)
     18 		b = mpnew(VLDIGITS*sizeof(mpdigit));
     19 	else
     20 		mpbits(b, VLDIGITS*sizeof(mpdigit));
     21 	mpassign(mpzero, b);
     22 	if(v == 0)
     23 		return b;
     24 	if(v < 0){
     25 		b->sign = -1;
     26 		uv = -v;
     27 	} else
     28 		uv = v;
     29 	for(s = 0; s < VLDIGITS && uv != 0; s++){
     30 		b->p[s] = uv;
     31 	/* !@*$&!@$ gcc gives warnings about the >> here
     32 	 * when running on 64-bit machines, even though
     33 	 * it's in dead code.  fake it out with two shifts.
     34 		if(sizeof(mpdigit) == sizeof(uvlong))
     35 			uv = 0;
     36 		else
     37 			uv >>= sizeof(mpdigit)*8;
     38 	*/
     39 		uv >>= sizeof(mpdigit)*4;
     40 		uv >>= sizeof(mpdigit)*4;
     41 	}
     42 	b->top = s;
     43 	return b;
     44 }
     45 
     46 vlong
     47 mptov(mpint *b)
     48 {
     49 	uvlong v;
     50 	int s;
     51 
     52 	if(b->top == 0)
     53 		return 0LL;
     54 
     55 	mpnorm(b);
     56 	if(b->top > VLDIGITS){
     57 		if(b->sign > 0)
     58 			return (vlong)MAXVLONG;
     59 		else
     60 			return (vlong)MINVLONG;
     61 	}
     62 
     63 	v = 0ULL;
     64 	for(s = 0; s < b->top; s++)
     65 		v |= b->p[s]<<(s*sizeof(mpdigit)*8);
     66 
     67 	if(b->sign > 0){
     68 		if(v > MAXVLONG)
     69 			v = MAXVLONG;
     70 	} else {
     71 		if(v > MINVLONG)
     72 			v = MINVLONG;
     73 		else
     74 			v = -(vlong)v;
     75 	}
     76 
     77 	return (vlong)v;
     78 }