shithub: femtolisp

ref: a69ae5ed2a33e8d1a62391e57347285228ba4054
dir: /3rd/mp/test/convtest.c/

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

/* these tests suck but better than nothing... but really should test more values than just 1<<i */

#define MPTOX(_name,_type,_func)  \
static void \
_name(void) \
{ \
	mpint *m; \
	int i, sign, mag; \
	_type v, e; \
	int fail; \
	 \
	fail = 0; \
	m = mpnew(0); \
	for(i = 0; i < 256; i++){ \
		sign = i >= 128 ? -1 : 1; \
		mag = i % 128; \
		itomp(sign, m); \
		mpleft(m, mag, m); \
		v = _func(m); \
		e = 0xcafebabe; USED(e);
#define MPTOX_END(_func,_format)  \
		if(v != e){ \
			fprintf(stderr, "FAIL: "#_func"(%s): return value: got "_format", expected "_format"\n", MFMT(m), v, e); \
			fail=1; \
		} \
	} \
	mpfree(m); \
	if(!fail) \
		fprintf(stderr, #_func": passed\n"); \
	anyfail |= fail; \
}

#define XTOMP(_name,_type,_func)  \
static void \
_name(void) \
{ \
	mpint *m, *r; \
	int i, sign, mag; \
	_type v; \
	int fail; \
	 \
	fail = 0; \
	m = mpnew(0); \
	r = mpnew(0); \
	for(i = 0; i < 256; i++){ \
		sign = i >= 128 ? -1 : 1; \
		mag = i % 128; \
		itomp(sign, r); \
		mpleft(r, mag, r);
#define XTOMP_END(_func,_type,_format)  \
		_func(sign * ((_type)1<<mag), m); \
		if(mpcmp(r, m) != 0){ \
			fprintf(stderr, "FAIL: "#_func"("_format"): return value: got %s, expected %s\n", sign * ((_type)1<<mag), MFMT(m), MFMT(r)); \
			fail=1; \
		} \
	} \
	mpfree(m); \
	mpfree(r); \
	if(!fail) \
		fprintf(stderr, #_func": passed\n"); \
	USED(v); \
	anyfail |= fail; \
}

MPTOX(test_mptoi, int, mptoi)
	if(mag < 31)
		e = sign*(1<<mag);
	else
		e = sign > 0 ? (1U<<31)-1 : 1U<<31;
MPTOX_END(mptoi, "%#x")

MPTOX(test_mptoui, uint32_t, mptoui)
	if(mag < 32 && sign > 0)
		e = 1<<mag;
	else
		e = sign > 0 ? -1 : 0;
MPTOX_END(mptoui, "%#x")


MPTOX(test_mptov, int64_t, mptov)
	if(mag < 63)
		e = sign*(1LL<<mag);
	else
		e = sign > 0 ? (1ULL<<63)-1 : 1ULL<<63;
MPTOX_END(mptov, "%#"PRIx64)

MPTOX(test_mptouv, uint64_t, mptouv)
	if(mag < 64 && sign > 0)
		e = 1LL<<mag;
	else
		e = sign > 0 ? -1ULL : 0;
MPTOX_END(mptouv, "%#"PRIx64)

XTOMP(test_itomp, int, itomp)
	if(mag >= 31) continue;
XTOMP_END(vtomp, int64_t, "%"PRId64)

XTOMP(test_uitomp, uint32_t, uitomp)
	if(mag >= 32 || sign < 0) continue;
XTOMP_END(uitomp, uint32_t, "%"PRIu32)

XTOMP(test_vtomp, int64_t, vtomp)
	if(mag >= 63) continue;
XTOMP_END(vtomp, int64_t, "%"PRId64)

XTOMP(test_uvtomp, uint64_t, uvtomp)
	if(mag >= 64 || sign < 0) continue;
XTOMP_END(uvtomp, int64_t, "%"PRId64)


void
convtests(void)
{
	test_mptoi();
	test_mptoui();
	test_mptov();
	test_mptouv();
	test_itomp();
	test_uitomp();
	test_vtomp();
	test_uvtomp();
}