xref: /inferno-os/libmp/port/mptov.c (revision 7ef44d652ae9e5e1f5b3465d73684e4a54de73c0)
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 		uv >>= sizeof(mpdigit)*8;
32 	}
33 	b->top = s;
34 	return b;
35 }
36 
37 vlong
38 mptov(mpint *b)
39 {
40 	uvlong v;
41 	int s;
42 
43 	if(b->top == 0)
44 		return 0;
45 
46 	mpnorm(b);
47 	if(b->top > VLDIGITS){
48 		if(b->sign > 0)
49 			return (vlong)MAXVLONG;
50 		else
51 			return (vlong)MINVLONG;
52 	}
53 
54 	v = 0;
55 	for(s = 0; s < b->top; s++)
56 		v |= b->p[s]<<(s*sizeof(mpdigit)*8);
57 
58 	if(b->sign > 0){
59 		if(v > MAXVLONG)
60 			v = MAXVLONG;
61 	} else {
62 		if(v > MINVLONG)
63 			v = MINVLONG;
64 		else
65 			v = -(vlong)v;
66 	}
67 
68 	return (vlong)v;
69 }
70