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 }