shithub: sl

ref: 24a71723ffbe92ccbdc088a078d776fb869b52ca
dir: /3rd/mp/mptov.c/

View raw version
#include "platform.h"
#include "mp.h"

#define VLDIGITS (int)(sizeof(s64int)/Dbytes)

/*
 *  this code assumes that a s64int is an integral number of
 *  mpdigits long.
 */
mpint*
vtomp(s64int v, mpint *b)
{
	int s;
	u64int uv;

	if(b == nil)
		b = mpnew(VLDIGITS*Dbits);
	else
		mpbits(b, VLDIGITS*Dbits);
	if(v == INT64_MIN){
		b->sign = -1;
		uv = (u64int)INT64_MAX+1;
	}else{
		b->sign = (v >> (sizeof(v)*8 - 1)) | 1;
		uv = v * b->sign;
	}
	for(s = 0; s < VLDIGITS; s++){
		b->p[s] = uv;
#ifndef BITS64
		uv >>= Dbits;
#endif
	}
	b->top = s;
	return mpnorm(b);
}

s64int
mptov(mpint *b)
{
	u64int v;
	u32int s;

	if(b->top == 0)
		return 0LL;

	if(b->top > VLDIGITS)
		return b->sign > 0 ? INT64_MAX : INT64_MIN;

	v = 0ULL;
	for(s = 0; s < b->top; s++)
		v |= (u64int)b->p[s]<<(s*Dbits);

	if(b->sign > 0){
		if(v > INT64_MAX)
			v = INT64_MAX;
	}else{
		v = v > INT64_MAX ? INT64_MIN : -(s64int)v;
	}

	return (s64int)v;
}