
///////////////////////////////////////////////////////////////////////////////
//                                                                           //
//                       Long Integer - test functions                       //
//                                                                           //
///////////////////////////////////////////////////////////////////////////////
// (c) 2021 Miroslav Nemecek, Panda38@seznam.cz, panda38.sweb.cz
// This source code may be used freely without restrictions for any purpose,
// including commercial.

// In this test, we compare result of tested number with result of reference number.
// Do set x2 first and x1 later - for case if x1 could modify source operands

/*
Use external defines:
--------------------
#define TESTINT uint64	// tested number class
#define REFINT u64		// reference number class
#define REFISCLS 0		// 1=reference number is class, 0=reference number is integer
#define BASEINT u32		// base integer
#define BASEBITS 32		// number of bits of base integer
#define HALFINT u16		// half integer
#define TESTBITS 64		// number of bits

#define SIGNED			// flag - signed number
#define FIXED			// flag - fix point number

// define only in case of quadint + number:
#define DBLINT1 uint32	// double integer class for tested number
#define DBLINT2 u32		// double integer for reference number
*/

#define HALFBITS (BASEBITS/2) // number of bits of half number

#ifdef DBLINT1
#define DBLBITS (BASEBITS*2) // number of bits of double number
#endif // DBLUINT

#ifdef FIXED

// fixed point simulated using s64 integer

#define REFS ((TESTBITS)/2)		// shifts of integer of reference number
#define REFX (1ULL << REFS)		// multiplier of reference number
#define MAXDIV ((((1ULL<<(TESTBITS-1))-1)<<1)+1) // max. divide value

#define A_REFINT (*(REFINT*)&a) // get reference number from a
#define B_REFINT (*(REFINT*)&b) // get reference number from b
#define A_BASEINT ((REFINT)*(BASEINT*)&a << REFS) // get reference base number from a
#define B_BASEINT ((REFINT)*(BASEINT*)&b << REFS) // get reference base number from b
#define A_HALFINT ((REFINT)*(HALFINT*)&a << REFS) // get reference half number from a
#define B_HALFINT ((REFINT)*(HALFINT*)&b << REFS) // get reference half number from b
#define A_DBLINT ((REFINT)*(DBLINT2*)&a << (REFS/2)) // get reference dblint number from a
#define B_DBLINT ((REFINT)*(DBLINT2*)&b << (REFS/2)) // get reference dblint number from b

#define REFADD(u,v) ((REFINT)(u) + (REFINT)(v)) // ADD reference number
#define REFSUB(u,v) ((REFINT)(u) - (REFINT)(v)) // SUB reference number
#define REFINC(u) ((REFINT)(u) + REFX) // INC reference number
#define REFDEC(u) ((REFINT)(u) - REFX) // DEC reference number

#define REFMUL(u,v) (REFINT)RefMul64(u, v, REFS) // MUL reference number
#define REFDIV(u,v) (REFINT)RefDiv64(u, v, REFS, MAXDIV) // DIV reference number
#define REFMOD(u,v) (REFINT)RefMod64(u, v) // MOD reference number

#define REFCMP(u) ((u) ? REFX : 0) // compare reference number

#define REFNOT(u) (~(REFINT)(u)) // NOT reference number
#define REFAND(u,v) ((REFINT)(u) & (REFINT)(v))	// AND reference number
#define REFOR(u,v) ((REFINT)(u) | (REFINT)(v))	// OR reference number
#define REFXOR(u,v) ((REFINT)(u) ^ (REFINT)(v))	// XOR reference number
#define REFSHL(u,s) ((REFINT)(u) << (s)) // shift left reference number
#define REFSHR(u,s) ((REFINT)(u) >> (s)) // shift right reference number

#else 

#define A_REFINT (*(REFINT*)&a) // get reference number from a
#define B_REFINT (*(REFINT*)&b) // get reference number from b
#define A_BASEINT (*(BASEINT*)&a) // get reference base number from a
#define B_BASEINT (*(BASEINT*)&b) // get reference base number from b
#define A_HALFINT (*(HALFINT*)&a) // get reference half number from a
#define B_HALFINT (*(HALFINT*)&b) // get reference half number from b
#define A_DBLINT (*(DBLINT2*)&a) // get reference dblint number from a
#define B_DBLINT (*(DBLINT2*)&b) // get reference dblint number from b

#define REFADD(u,v) ((REFINT)(u) + (REFINT)(v)) // ADD reference number
#define REFSUB(u,v) ((REFINT)(u) - (REFINT)(v)) // SUB reference number
#define REFINC(u) ((REFINT)(u) + 1) // INC reference number
#define REFDEC(u) ((REFINT)(u) - 1) // DEC reference number

#define REFMUL(u,v) ((REFINT)(u) * (REFINT)(v)) // MUL reference number
#define REFDIV(u,v) ((REFINT)(u) / (REFINT)(v)) // DIV reference number
#define REFMOD(u,v) ((REFINT)(u) % (REFINT)(v)) // MOD reference number

#define REFCMP(u) (BASEINT)((u) ? 1 : 0) // compare reference number

#define REFNOT(u) (~(REFINT)(u)) // NOT reference number
#define REFAND(u,v) ((REFINT)(u) & (REFINT)(v))	// AND reference number
#define REFOR(u,v) ((REFINT)(u) | (REFINT)(v))	// OR reference number
#define REFXOR(u,v) ((REFINT)(u) ^ (REFINT)(v))	// XOR reference number
#define REFSHL(u,s) ((REFINT)(u) << (s)) // shift left reference number
#define REFSHR(u,s) ((REFINT)(u) >> (s)) // shift right reference number

#endif // FIXED

// Note: variables must be declared as static to avoid stack harming.

// operands of tested number class
static TESTINT x1 = (BASEINT)0;
static TESTINT x1old = x1;

// operands of reference number class
static REFINT x2 = (BASEINT)0;
static REFINT x2old = x2;

// temporary random operands
static TESTINT a = (BASEINT)0;
static TESTINT b = (BASEINT)0;
static int shift = 0;

static int cat = -1; // category
static int op = -1; // operation
static int i = 0;

// loop through all tests
for (i = 0; i != max; i++)
{
	// compare operands
	if (memcmp(&x1, &x2, TESTBITS/8) != 0)
	{
		printf("\r%s ERROR cat=%d op=%d\n", name, cat, op);
		PrintTestHex("a", &a, TESTBITS);
		PrintTestHex("b", &b, TESTBITS);

		printf("\n new:\n");
		PrintTestHex("x1", &x1, TESTBITS);
		PrintTestHex("x2", &x2, TESTBITS);

		printf("\n old:\n");
		PrintTestHex("x1", &x1old, TESTBITS);
		PrintTestHex("x2", &x2old, TESTBITS);

		printf("\n");

#ifdef _MSC_VER
		exit(2);
#else
		while (True) {}
#endif
	}

	// progress indicator
#ifdef _MSC_VER
	if ((i & 0xfffff) == 0)
#else
	if ((i & 0x7fff) == 0)
#endif
	{
		printf("\r%s: %02u%% ", name, (unsigned int)((u64)i*100/max));
	}

	// save old value of operands
	x1old = x1;
	x2old = x2;

	// switch category
	cat = (int)Rand(26);
	switch (cat)
	{

// --- constructor

	// cat=0
	case 0:
		op = (int)Rand(4);
		switch (op)
		{
		case 0:
			{
				RandBits(&a, TESTBITS);
				x2 = A_REFINT;
				TESTINT t(a);
				x1 = t;
			}
			break;

		case 1:
			{
				RandBits(&a, BASEBITS);
				x2 = A_BASEINT;
				TESTINT t(*(BASEINT*)&a);
				x1 = t;
			}
			break;

		case 2:
			{
				TESTINT t(x1);
				x1 = t;
			}
			break;

		case 3:
			{
				a = (BASEINT)123;
				x2 = A_REFINT;
				TESTINT t((BASEINT)123);
				x1 = t;
			}
			break;

#ifdef DBLINT1
		case 4:
			{
				RandBits(&a, DBLBITS);
				x2 = A_DBLINT;
				TESTINT t(*(DBLINT1*)&a);
				x1 = t;
			}
			break;
#endif // DBLINT1
		}
		break;

// --- SET =

	// cat=1
	case 1:
		op = (int)Rand(9);
		switch (op)
		{
		case 0: // this = 0
			a = (BASEINT)0;
			x2 = A_REFINT;
			x1.Set0();
			break;

		case 1: // this = 1
			a = (BASEINT)1;
			x2 = A_REFINT;
			x1.Set1();
			break;

		case 2: // this = -1
			a = (BASEINT)0;
			a--;
			x2 = A_REFINT;
			x1.SetM1();
			break;

		case 3: // this = num
			RandBits(&a, TESTBITS);
			x2 = A_REFINT;
			x1.Set(a);
			break;

		case 4: // this = this
			x1.Set(x1);
			break;

		case 5: // this = 0:num
			RandBits(&a, BASEBITS);
			x2 = A_BASEINT;
			x1.Set(*(BASEINT*)&a);
			break;

		case 6: // this = int
			a = (BASEINT)123;
			x2 = A_REFINT;
			x1.Set((BASEINT)123);
			break;

		case 7: // exchange two numbers 1
			RandBits(&a, TESTBITS);
			x2 = A_REFINT;
			x1.Exchange(a);
			break;

		case 8: // exchange two numbers 2
			RandBits(&a, TESTBITS);
			x1.Exchange(a);
			x1 = a;
			break;

#ifdef DBLINT1
		case 9: // this = 0:num
			RandBits(&a, DBLBITS);
			x2 = A_DBLINT;
			x1.Set(*(DBLINT1*)&a);
			break;
#endif // DBLINT1
		}
		break;

// --- ADD +

	// cat=2
	case 2:
		op = (int)Rand(18);
		switch (op)
		{
		case 0: // this += num
			RandBits(&a, TESTBITS);
			x2 = REFADD(x2, A_REFINT);
			x1.Add(a);
			break;

		case 1: // this += this
			x2 = REFADD(x2, x2);
			x1.Add(x1);
			break;

		case 2: // this += 0:num
			RandBits(&a, BASEBITS);
			x2 = REFADD(x2, A_BASEINT);
			x1.Add(*(BASEINT*)&a);
			break;

		case 3: // this += int
			a = (BASEINT)123;
			x2 = REFADD(x2, A_REFINT);
			x1.Add((BASEINT)123);
			break;

		case 4: // this = num1 + num2
			RandBits(&a, TESTBITS);
			RandBits(&b, TESTBITS);
			x2 = REFADD(A_REFINT, B_REFINT);
			x1.Add(a, b);
			break;

		case 5: // this = this + num2
			RandBits(&a, TESTBITS);
			x2 = REFADD(x2, A_REFINT);
			x1.Add(x1, a);
			break;

		case 6: // this = num1 + this
			RandBits(&a, TESTBITS);
			x2 = REFADD(A_REFINT, x2);
			x1.Add(a, x1);
			break;

		case 7: // this = num1 + 0:num2
			RandBits(&a, TESTBITS);
			RandBits(&b, BASEBITS);
			x2 = REFADD(A_REFINT, B_BASEINT);
			x1.Add(a, *(BASEINT*)&b);
			break;

		case 8: // this = 0:num1 + num2
			RandBits(&a, BASEBITS);
			RandBits(&b, TESTBITS);
			x2 = REFADD(A_BASEINT, B_REFINT);
			x1.Add(*(BASEINT*)&a, b);
			break;

		case 9: // this = this + 0:num2
			RandBits(&b, BASEBITS);
			x2 = REFADD(x2, B_BASEINT);
			x1.Add(x1, *(BASEINT*)&b);
			break;

		case 10: // this = 0:num1 + this
			RandBits(&a, BASEBITS);
			x2 = REFADD(A_BASEINT, x2);
			x1.Add(*(BASEINT*)&a, x1);
			break;

		case 11: // this = num1 + int
			RandBits(&a, TESTBITS);
			b = (BASEINT)123;
			x2 = REFADD(A_REFINT, B_REFINT);
			x1.Add(a, (BASEINT)123);
			break;

		case 12: // this = int + num2
			a = (BASEINT)123;
			RandBits(&b, TESTBITS);
			x2 = REFADD(A_REFINT, B_REFINT);
			x1.Add((BASEINT)123, b);
			break;

		case 13: // this = this + this
			RandBits(&a, TESTBITS);
			x2 = A_REFINT;
			x1 = a;
			x2 = REFADD(x2, x2);
			x1.Add(x1, x1);
			break;

#ifdef DBLINT1
		case 14: // this += 0:num
			RandBits(&a, DBLBITS);
			x2 = REFADD(x2, A_DBLINT);
			x1.Add(*(DBLINT1*)&a);
			break;

		case 15: // this = num1 + 0:num2
			RandBits(&a, TESTBITS);
			RandBits(&b, DBLBITS);
			x2 = REFADD(A_REFINT, B_DBLINT);
			x1.Add(a, *(DBLINT1*)&b);
			break;

		case 16: // this = 0:num1 + num2
			RandBits(&a, DBLBITS);
			RandBits(&b, TESTBITS);
			x2 = REFADD(A_DBLINT, B_REFINT);
			x1.Add(*(DBLINT1*)&a, b);
			break;

		case 17: // this = this + 0:num2
			RandBits(&b, DBLBITS);
			x2 = REFADD(x2, B_DBLINT);
			x1.Add(x1, *(DBLINT1*)&b);
			break;

		case 18: // this = 0:num1 + this
			RandBits(&a, DBLBITS);
			x2 = REFADD(A_DBLINT, x2);
			x1.Add(*(DBLINT1*)&a, x1);
			break;
#endif // DBLINT1
		}
		break;

// --- SUB -

	// cat=3
	case 3:
		op = (int)Rand(22);
		switch (op)
		{
		case 0: // this -= num
			RandBits(&a, TESTBITS);
			x2 = REFSUB(x2, A_REFINT);
			x1.Sub(a);
			break;

		case 1: // this -= this
			x2 = REFSUB(x2, x2);
			x1.Sub(x1);
			break;

		case 2: // this -= 0:num
			RandBits(&a, BASEBITS);
			x2 = REFSUB(x2, A_BASEINT);
			x1.Sub(*(BASEINT*)&a);
			break;

		case 3: // this -= int
			a = (BASEINT)123;
			x2 = REFSUB(x2, A_REFINT);
			x1.Sub((BASEINT)123);
			break;

		case 4: // this = num1 - num2
			RandBits(&a, TESTBITS);
			RandBits(&b, TESTBITS);
			x2 = REFSUB(A_REFINT, B_REFINT);
			x1.Sub(a, b);
			break;

		case 5: // this = this - num2
			RandBits(&a, TESTBITS);
			x2 = REFSUB(x2, A_REFINT);
			x1.Sub(x1, a);
			break;

		case 6: // this = num1 - this
			RandBits(&a, TESTBITS);
			x2 = REFSUB(A_REFINT, x2);
			x1.Sub(a, x1);
			break;

		case 7: // this = num1 - 0:num2
			RandBits(&a, TESTBITS);
			RandBits(&b, BASEBITS);
			x2 = REFSUB(A_REFINT, B_BASEINT);
			x1.Sub(a, *(BASEINT*)&b);
			break;

		case 8: // this = 0:num1 - num2
			RandBits(&a, BASEBITS);
			RandBits(&b, TESTBITS);
			x2 = REFSUB(A_BASEINT, B_REFINT);
			x1.Sub(*(BASEINT*)&a, b);
			break;

		case 9: // this = this - 0:num2
			RandBits(&b, BASEBITS);
			x2 = REFSUB(x2, B_BASEINT);
			x1.Sub(x1, *(BASEINT*)&b);
			break;

		case 10: // this = 0:num1 - this
			RandBits(&a, BASEBITS);
			x2 = REFSUB(A_BASEINT, x2);
			x1.Sub(*(BASEINT*)&a, x1);
			break;

		case 11: // this = num1 - int
			RandBits(&a, TESTBITS);
			b = (BASEINT)123;
			x2 = REFSUB(A_REFINT, B_REFINT);
			x1.Sub(a, (BASEINT)123);
			break;

		case 12: // this = int - num2
			a = (BASEINT)123;
			RandBits(&b, TESTBITS);
			x2 = REFSUB(A_REFINT, B_REFINT);
			x1.Sub((BASEINT)123, b);
			break;

		case 13: // this = num - this
			RandBits(&a, TESTBITS);
			x2 = REFSUB(A_REFINT, x2);
			x1.RevSub(a);
			break;

		case 14: // this = 0:num - this
			RandBits(&a, BASEBITS);
			x2 = REFSUB(A_BASEINT, x2);
			x1.RevSub(*(BASEINT*)&a);
			break;

		case 15: // this = int - this
			a = (BASEINT)123;
			x2 = REFSUB(A_REFINT, x2);
			x1.RevSub((BASEINT)123);
			break;

		case 16: // this = this - this
			RandBits(&a, TESTBITS);
			x2 = A_REFINT;
			x1 = a;
			x2 = REFSUB(x2, x2);
			x1.Sub(x1, x1);
			break;

#ifdef DBLINT1
		case 17: // this -= 0:num
			RandBits(&a, DBLBITS);
			x2 = REFSUB(x2, A_DBLINT);
			x1.Sub(*(DBLINT1*)&a);
			break;

		case 18: // this = num1 - 0:num2
			RandBits(&a, TESTBITS);
			RandBits(&b, DBLBITS);
			x2 = REFSUB(A_REFINT, B_DBLINT);
			x1.Sub(a, *(DBLINT1*)&b);
			break;

		case 19: // this = 0:num1 - num2
			RandBits(&a, DBLBITS);
			RandBits(&b, TESTBITS);
			x2 = REFSUB(A_DBLINT, B_REFINT);
			x1.Sub(*(DBLINT1*)&a, b);
			break;

		case 20: // this = this - 0:num2
			RandBits(&b, DBLBITS);
			x2 = REFSUB(x2, B_DBLINT);
			x1.Sub(x1, *(DBLINT1*)&b);
			break;

		case 21: // this = 0:num1 - this
			RandBits(&a, DBLBITS);
			x2 = REFSUB(A_DBLINT, x2);
			x1.Sub(*(DBLINT1*)&a, x1);
			break;

		case 22: // this = 0:num - this
			RandBits(&a, DBLBITS);
			x2 = REFSUB(A_DBLINT, x2);
			x1.RevSub(*(DBLINT1*)&a);
			break;
#endif // DBLINT1
		}
		break;

// --- increment ++ and decrement --

	// cat=4
	case 4:
		op = (int)Rand(3);
		switch (op)
		{
		case 0: // this++
			x2 = REFINC(x2);
			x1.Inc();
			break;

		case 1: // this = num + 1
			RandBits(&a, TESTBITS);
			x2 = REFINC(A_REFINT);
			x1.Inc(a);
			break;

		case 2: // this--
			x2 = REFDEC(x2);
			x1.Dec();
			break;

		case 3: // this = num - 1
			RandBits(&a, TESTBITS);
			x2 = REFDEC(A_REFINT);
			x1.Dec(a);
			break;
		}
		break;

// --- MUL * and SQR

	// cat=5
	case 5:
		op = (int)Rand(31);
		switch (op)
		{
		case 0: // this *= num
			RandBits(&a, TESTBITS);
			x2 = REFMUL(x2, A_REFINT);
			x1.Mul(a);
			break;

		case 1: // this *= this
			x2 = REFMUL(x2, x2);
			x1.Mul(x1);
			break;

		case 2: // this *= 0:num
			RandBits(&a, BASEBITS);
			x2 = REFMUL(x2, A_BASEINT);
			x1.Mul(*(BASEINT*)&a);
			break;

		case 3: // this *= int
			a = (BASEINT)123;
			x2 = REFMUL(x2, A_REFINT);
			x1.Mul((BASEINT)123);
			break;

		case 4: // this *= 10
			a = (BASEINT)10;
			x2 = REFMUL(x2, A_REFINT);
			x1.Mul10();
			break;

		case 5: // this = num1 * num2
			RandBits(&a, TESTBITS);
			RandBits(&b, TESTBITS);
			x2 = REFMUL(A_REFINT, B_REFINT);
			x1.Mul(a, b);
			break;

		case 6: // this = this * num2
			RandBits(&a, TESTBITS);
			x2 = REFMUL(x2, A_REFINT);
			x1.Mul(x1, a);
			break;

		case 7: // this = num1 * this
			RandBits(&a, TESTBITS);
			x2 = REFMUL(A_REFINT, x2);
			x1.Mul(a, x1);
			break;

		case 8: // this = num1 * 0:num2
			RandBits(&a, TESTBITS);
			RandBits(&b, BASEBITS);
			x2 = REFMUL(A_REFINT, B_BASEINT);
			x1.Mul(a, *(BASEINT*)&b);
			break;

		case 9: // this = 0:num1 * num2
			RandBits(&a, BASEBITS);
			RandBits(&b, TESTBITS);
			x2 = REFMUL(A_BASEINT, B_REFINT);
			x1.Mul(*(BASEINT*)&a, b);
			break;

		case 10: // this = this * 0:num2
			RandBits(&b, BASEBITS);
			x2 = REFMUL(x2, B_BASEINT);
			x1.Mul(x1, *(BASEINT*)&b);
			break;

		case 11: // this = 0:num1 * this
			RandBits(&a, BASEBITS);
			x2 = REFMUL(A_BASEINT, x2);
			x1.Mul(*(BASEINT*)&a, x1);
			break;

		case 12: // this = num1 * int
			RandBits(&a, TESTBITS);
			b = (BASEINT)123;
			x2 = REFMUL(A_REFINT, B_REFINT);
			x1.Mul(a, (BASEINT)123);
			break;

		case 13: // this = int * num2
			a = (BASEINT)123;
			RandBits(&b, TESTBITS);
			x2 = REFMUL(A_REFINT, B_REFINT);
			x1.Mul((BASEINT)123, b);
			break;

		case 14: // this = 0:num1 * 0:num2
			RandBits(&a, BASEBITS);
			RandBits(&b, BASEBITS);
			x2 = REFMUL(A_BASEINT, B_BASEINT);
			x1.Mul(*(BASEINT*)&a, *(BASEINT*)&b);
			break;

		case 15: // this = 0:num * int
			RandBits(&a, BASEBITS);
			b = (BASEINT)123;
			x2 = REFMUL(A_BASEINT, B_REFINT);
			x1.Mul(*(BASEINT*)&a, (BASEINT)123);
			break;

		case 16: // this = int * 0:num
			a = (BASEINT)123;
			RandBits(&b, BASEBITS);
			x2 = REFMUL(A_REFINT, B_BASEINT);
			x1.Mul((BASEINT)123, *(BASEINT*)&b);
			break;

		case 17: // this *= this
			x2 = REFMUL(x2, x2);
			x1.Sqr();
			break;

		case 18: // this = num * num
			RandBits(&a, TESTBITS);
			x2 = REFMUL(A_REFINT, A_REFINT);
			x1.Sqr(a);
			break;

		case 19: // this = 0:num * 0:num
			RandBits(&a, BASEBITS);
			x2 = REFMUL(A_BASEINT, A_BASEINT);
			x1.Sqr(*(BASEINT*)&a);
			break;

		case 20: // this = int * int
			a = (BASEINT)123;
			x2 = REFMUL(A_REFINT, A_REFINT);
			x1.Sqr((BASEINT)123);
			break;

		case 21: // this = this * this
			RandBits(&a, TESTBITS);
			x2 = A_REFINT;
			x1 = a;
			x2 = REFMUL(x2, x2);
			x1.Mul(x1, x1);
			break;

		case 22: // this = num * 10
			RandBits(&a, TESTBITS);
			b = (BASEINT)10;
			x2 = REFMUL(A_REFINT, B_REFINT);
			x1.Mul10(a);
			break;

#ifdef DBLINT1
		case 23: // this *= 0:num
			RandBits(&a, DBLBITS);
			x2 = REFMUL(x2, A_DBLINT);
			x1.Mul(*(DBLINT1*)&a);
			break;

		case 24: // this = num1 * 0:num2
			RandBits(&a, TESTBITS);
			RandBits(&b, DBLBITS);
			x2 = REFMUL(A_REFINT, B_DBLINT);
			x1.Mul(a, *(DBLINT1*)&b);
			break;

		case 25: // this = 0:num1 * num2
			RandBits(&a, DBLBITS);
			RandBits(&b, TESTBITS);
			x2 = REFMUL(A_DBLINT, B_REFINT);
			x1.Mul(*(DBLINT1*)&a, b);
			break;

		case 26: // this = this * 0:num2
			RandBits(&b, DBLBITS);
			x2 = REFMUL(x2, B_DBLINT);
			x1.Mul(x1, *(DBLINT1*)&b);
			break;

		case 27: // this = 0:num1 * this
			RandBits(&a, DBLBITS);
			x2 = REFMUL(A_DBLINT, x2);
			x1.Mul(*(DBLINT1*)&a, x1);
			break;

		case 28: // this = 0:num1 * 0:num2
			RandBits(&a, DBLBITS);
			RandBits(&b, DBLBITS);
			x2 = REFMUL(A_DBLINT, B_DBLINT);
			x1.Mul(*(DBLINT1*)&a, *(DBLINT1*)&b);
			break;

		case 29: // this = 0:num1 * 0:0:0:num2
			RandBits(&a, DBLBITS);
			RandBits(&b, BASEBITS);
			x2 = REFMUL(A_DBLINT, B_BASEINT);
			x1.Mul(*(DBLINT1*)&a, *(BASEINT*)&b);
			break;

		case 30: // this = 0:0:0:num1 * 0:num2
			RandBits(&a, BASEBITS);
			RandBits(&b, DBLBITS);
			x2 = REFMUL(A_BASEINT, B_DBLINT);
			x1.Mul(*(BASEINT*)&a, *(DBLINT1*)&b);
			break;

		case 31: // this = 0:num * 0:num
			RandBits(&a, DBLBITS);
			x2 = REFMUL(A_DBLINT, A_DBLINT);
			x1.Sqr(*(DBLINT1*)&a);
			break;
#endif // DBLINT1
		}
		break;

// --- DIV / and MOD %

	// cat=6
	case 6:
		op = (int)Rand(11);
		switch (op)
		{
		case 0: // this = num1 / 0:0:0:num2, returns remainder
			RandBits(&a, TESTBITS);
			RandBits(&b, HALFBITS);
			*(BASEINT*)&b = *(HALFINT*)&b;
			if (*(BASEINT*)&b == (BASEINT)0) *(BASEINT*)&b = (BASEINT)1;
			x2 = REFDIV(A_REFINT, B_BASEINT); // HALFINT is ambiquous
			x1.Div(a, *(HALFINT*)&b);
			break;

		case 1: // this = num1 % 0:0:0:num2, returns remainder
			RandBits(&a, TESTBITS);
			RandBits(&b, HALFBITS);
			*(BASEINT*)&b = *(HALFINT*)&b;
			if (*(BASEINT*)&b == (BASEINT)0) *(BASEINT*)&b = (BASEINT)1;
			x2 = REFMOD(A_REFINT, B_BASEINT); // HALFINT is ambiquous
			x1.Mod(a, *(HALFINT*)&b);
			break;

		case 2: // this = num1 / 0:num2, returns remainder
			RandBits(&a, TESTBITS);
			RandBits(&b, BASEBITS);
			if (*(BASEINT*)&b == (BASEINT)0) *(BASEINT*)&b = (BASEINT)1;
			x2 = REFDIV(A_REFINT, B_BASEINT);
			x1.Div(a, *(BASEINT*)&b);
			break;

		case 3: // this = num1 % 0:num2, returns remainder
			RandBits(&a, TESTBITS);
			RandBits(&b, BASEBITS);
			if (*(BASEINT*)&b == (BASEINT)0) *(BASEINT*)&b = (BASEINT)1;
			x2 = REFMOD(A_REFINT, B_BASEINT);
			x1.Mod(a, *(BASEINT*)&b);
			break;

		case 4: // this = num1 / num2
			RandBits(&a, TESTBITS);
			RandBits(&b, TESTBITS);
			if (b.Equ0()) b.Set1();
			x2 = REFDIV(A_REFINT, B_REFINT);
			x1.Div(a, b);
			break;

		case 5: // this = num1 % num2
			RandBits(&a, TESTBITS);
			RandBits(&b, TESTBITS);
			if (b.Equ0()) b.Set1();
			x2 = REFMOD(A_REFINT, B_REFINT);
			x1.Mod(a, b);
			break;

		case 6: // this = num / 10, returns remainder
			RandBits(&a, TESTBITS);
			b = (BASEINT)10;
			x2 = REFDIV(A_REFINT, B_REFINT);
			x1.Div10(a);
			break;

		case 7: // this = num % 10, returns remainder
			RandBits(&a, TESTBITS);
			b = (BASEINT)10;
			x2 = REFMOD(A_REFINT, B_REFINT);
			x1.Mod10(a);
			break;

#ifndef FIXED
		case 8: // this = num1 / num2 (FastDiv)
			RandBits(&a, TESTBITS);
			RandBits(&b, TESTBITS);
			if (b.Equ0()) b.Set1();
			x2 = REFDIV(A_REFINT, B_REFINT);
			x1.TestFastDiv(a, b);
			break;

		case 9: // this = num1 % num2 (FastDiv)
			RandBits(&a, TESTBITS);
			RandBits(&b, TESTBITS);
			if (b.Equ0()) b.Set1();
			x2 = REFMOD(A_REFINT, B_REFINT);
			x1.TestFastMod(a, b);
			break;
#endif // FIXED

#ifdef DBLINT1
		case 10: // this = num1 / num2
			RandBits(&a, TESTBITS);
			RandBits(&b, DBLBITS);
			if (*(DBLINT1*)&b == (BASEINT)0) *(DBLINT1*)&b = (BASEINT)1;
			x2 = REFDIV(A_REFINT, B_DBLINT);
			x1.Div(a, *(DBLINT1*)&b);
			break;

		case 11: // this = num1 % num2
			RandBits(&a, TESTBITS);
			RandBits(&b, DBLBITS);
			if (*(DBLINT1*)&b == (BASEINT)0) *(DBLINT1*)&b = (BASEINT)1;
			x2 = REFMOD(A_REFINT, B_DBLINT);
			x1.Mod(a, *(DBLINT1*)&b);
			break;
#endif // DBLINT1
		}
		break;

// --- comparisons ==

	// cat=7
	case 7:
		op = (int)Rand(27);
		switch (op)
		{
		case 0: // this == 0
			RandBits(&a, TESTBITS);
			x2 = A_REFINT;
			x1 = a;
			x2 = REFCMP(x2 == 0);
			x1 = (BASEINT)(x1.Equ0() ? 1 : 0);
			break;

		case 1: // this == 1
			RandBits(&a, TESTBITS);
			b = (BASEINT)1;
			x2 = A_REFINT;
			x1 = a;
			x2 = REFCMP(x2 == B_REFINT);
			x1 = (BASEINT)(x1.Equ1() ? 1 : 0);
			break;

		case 2: // this == num
			RandBits(&a, TESTBITS);
			RandBits(&b, TESTBITS);
			x2 = A_REFINT;
			x1 = a;
			x2 = REFCMP(x2 == B_REFINT);
			x1 = (BASEINT)(x1.Equ(b) ? 1 : 0);
			break;

		case 3: // this == 0:num
			RandBits(&a, TESTBITS);
			RandBits(&b, BASEBITS);
			x2 = A_REFINT;
			x1 = a;
			x2 = REFCMP(x2 == B_BASEINT);
			x1 = (BASEINT)(x1.Equ(*(BASEINT*)&b) ? 1 : 0);
			break;

		case 4: // this == int
			RandBits(&a, TESTBITS);
			b = (BASEINT)123;
			x2 = A_REFINT;
			x1 = a;
			x2 = REFCMP(x2 == B_REFINT);
			x1 = (BASEINT)(x1.Equ((BASEINT)123) ? 1 : 0);
			break;

		case 5: // this != 0
			RandBits(&a, TESTBITS);
			x2 = A_REFINT;
			x1 = a;
			x2 = REFCMP(x2 != 0);
			x1 = (BASEINT)(x1.NEqu0() ? 1 : 0);
			break;

		case 6: // this != 1
			RandBits(&a, TESTBITS);
			b = (BASEINT)1;
			x2 = A_REFINT;
			x1 = a;
			x2 = REFCMP(x2 != B_REFINT);
			x1 = (BASEINT)(x1.NEqu1() ? 1 : 0);
			break;

		case 7: // this != num
			RandBits(&a, TESTBITS);
			RandBits(&b, TESTBITS);
			x2 = A_REFINT;
			x1 = a;
			x2 = REFCMP(x2 != B_REFINT);
			x1 = (BASEINT)(x1.NEqu(b) ? 1 : 0);
			break;

		case 8: // this != 0:num
			RandBits(&a, TESTBITS);
			RandBits(&b, BASEBITS);
			x2 = A_REFINT;
			x1 = a;
			x2 = REFCMP(x2 != B_BASEINT);
			x1 = (BASEINT)(x1.NEqu(*(BASEINT*)&b) ? 1 : 0);
			break;

		case 9: // this != int
			RandBits(&a, TESTBITS);
			b = (BASEINT)123;
			x2 = A_REFINT;
			x1 = a;
			x2 = REFCMP(x2 != B_REFINT);
			x1 = (BASEINT)(x1.NEqu((BASEINT)123) ? 1 : 0);
			break;

		case 10: // this < num
			RandBits(&a, TESTBITS);
			RandBits(&b, TESTBITS);
			x2 = A_REFINT;
			x1 = a;
			x2 = REFCMP(x2 < B_REFINT);
			x1 = (BASEINT)(x1.Less(b) ? 1 : 0);
			break;

		case 11: // this < 0:num
			RandBits(&a, TESTBITS);
			RandBits(&b, BASEBITS);
			x2 = A_REFINT;
			x1 = a;
			x2 = REFCMP(x2 < B_BASEINT);
			x1 = (BASEINT)(x1.Less(*(BASEINT*)&b) ? 1 : 0);
			break;

		case 12: // this < int
			RandBits(&a, TESTBITS);
			b = (BASEINT)123;
			x2 = A_REFINT;
			x1 = a;
			x2 = REFCMP(x2 < B_REFINT);
			x1 = (BASEINT)(x1.Less((BASEINT)123) ? 1 : 0);
			break;

		case 13: // this <= num
			RandBits(&a, TESTBITS);
			RandBits(&b, TESTBITS);
			x2 = A_REFINT;
			x1 = a;
			x2 = REFCMP(x2 <= B_REFINT);
			x1 = (BASEINT)(x1.LessEqu(b) ? 1 : 0);
			break;

		case 14: // this <= 0:num
			RandBits(&a, TESTBITS);
			RandBits(&b, BASEBITS);
			x2 = A_REFINT;
			x1 = a;
			x2 = REFCMP(x2 <= B_BASEINT);
			x1 = (BASEINT)(x1.LessEqu(*(BASEINT*)&b) ? 1 : 0);
			break;

		case 15: // this <= int
			RandBits(&a, TESTBITS);
			b = (BASEINT)123;
			x2 = A_REFINT;
			x1 = a;
			x2 = REFCMP(x2 <= B_REFINT);
			x1 = (BASEINT)(x1.LessEqu((BASEINT)123) ? 1 : 0);
			break;
		
		case 16: // this > num
			RandBits(&a, TESTBITS);
			RandBits(&b, TESTBITS);
			x2 = A_REFINT;
			x1 = a;
			x2 = REFCMP(x2 > B_REFINT);
			x1 = (BASEINT)(x1.Greater(b) ? 1 : 0);
			break;

		case 17: // this > 0:num
			RandBits(&a, TESTBITS);
			RandBits(&b, BASEBITS);
			x2 = A_REFINT;
			x1 = a;
			x2 = REFCMP(x2 > B_BASEINT);
			x1 = (BASEINT)(x1.Greater(*(BASEINT*)&b) ? 1 : 0);
			break;

		case 18: // this > int
			RandBits(&a, TESTBITS);
			b = (BASEINT)123;
			x2 = A_REFINT;
			x1 = a;
			x2 = REFCMP(x2 > B_REFINT);
			x1 = (BASEINT)(x1.Greater((BASEINT)123) ? 1 : 0);
			break;

		case 19: // this >= num
			RandBits(&a, TESTBITS);
			RandBits(&b, TESTBITS);
			x2 = A_REFINT;
			x1 = a;
			x2 = REFCMP(x2 >= B_REFINT);
			x1 = (BASEINT)(x1.GreaterEqu(b) ? 1 : 0);
			break;

		case 20: // this >= 0:num
			RandBits(&a, TESTBITS);
			RandBits(&b, BASEBITS);
			x2 = A_REFINT;
			x1 = a;
			x2 = REFCMP(x2 >= B_BASEINT);
			x1 = (BASEINT)(x1.GreaterEqu(*(BASEINT*)&b) ? 1 : 0);
			break;

		case 21: // this >= int
			RandBits(&a, TESTBITS);
			b = (BASEINT)123;
			x2 = A_REFINT;
			x1 = a;
			x2 = REFCMP(x2 >= B_REFINT);
			x1 = (BASEINT)(x1.GreaterEqu((BASEINT)123) ? 1 : 0);
			break;

#ifdef DBLINT1
		case 22: // this == 0:num
			RandBits(&a, TESTBITS);
			RandBits(&b, DBLBITS);
			x2 = A_REFINT;
			x1 = a;
			x2 = REFCMP(x2 == B_DBLINT);
			x1 = (BASEINT)(x1.Equ(*(DBLINT1*)&b) ? 1 : 0);
			break;

		case 23: // this != 0:num
			RandBits(&a, TESTBITS);
			RandBits(&b, DBLBITS);
			x2 = A_REFINT;
			x1 = a;
			x2 = REFCMP(x2 != B_DBLINT);
			x1 = (BASEINT)(x1.NEqu(*(DBLINT1*)&b) ? 1 : 0);
			break;

		case 24: // this < 0:num
			RandBits(&a, TESTBITS);
			RandBits(&b, DBLBITS);
			x2 = A_REFINT;
			x1 = a;
			x2 = REFCMP(x2 < B_DBLINT);
			x1 = (BASEINT)(x1.Less(*(DBLINT1*)&b) ? 1 : 0);
			break;

		case 25: // this <= 0:num
			RandBits(&a, TESTBITS);
			RandBits(&b, DBLBITS);
			x2 = A_REFINT;
			x1 = a;
			x2 = REFCMP(x2 <= B_DBLINT);
			x1 = (BASEINT)(x1.LessEqu(*(DBLINT1*)&b) ? 1 : 0);
			break;

		case 26: // this > 0:num
			RandBits(&a, TESTBITS);
			RandBits(&b, DBLBITS);
			x2 = A_REFINT;
			x1 = a;
			x2 = REFCMP(x2 > B_DBLINT);
			x1 = (BASEINT)(x1.Greater(*(DBLINT1*)&b) ? 1 : 0);
			break;

		case 27: // this >= 0:num
			RandBits(&a, TESTBITS);
			RandBits(&b, DBLBITS);
			x2 = A_REFINT;
			x1 = a;
			x2 = REFCMP(x2 >= B_DBLINT);
			x1 = (BASEINT)(x1.GreaterEqu(*(DBLINT1*)&b) ? 1 : 0);
			break;

#endif // DBLINT1
		}
		break;

// --- NEG

	// cat=8
	case 8:
		op = (int)Rand(4);
		switch (op)
		{
		case 0: // this = -this
			RandBits(&a, TESTBITS);
			x2 = A_REFINT;
			x1 = a;
			x2 = -x2;
			x1.Neg();
			break;

		case 1: // this = -num
			RandBits(&a, TESTBITS);
			x2 = -A_REFINT;
			x1.Neg(a);
			break;

		case 2: // this = -0:num
			RandBits(&a, BASEBITS);
			x2 = A_BASEINT;
			x2 = -x2;
			x1.Neg(*(BASEINT*)&a);
			break;

		case 3: // this = -int
			a = (BASEINT)123;
			x2 = -A_REFINT;
			x1.Neg((BASEINT)123);
			break;
		
#ifdef DBLINT1
		case 4: // this = -0:num
			RandBits(&a, DBLBITS);
			x2 = A_DBLINT;
			x2 = -x2;
			x1.Neg(*(DBLINT1*)&a);
			break;

#endif // DBLINT1
		}
		break;

// --- NOT ~

	// cat=9
	case 9:
		op = (int)Rand(3);
		switch (op)
		{
		case 0: // this = ~this
			RandBits(&a, TESTBITS);
			x2 = A_REFINT;
			x1 = a;
			x2 = REFNOT(x2);
			x1.Not();
			break;

		case 1: // this = ~num
			RandBits(&a, TESTBITS);
			x2 = REFNOT(A_REFINT);
			x1.Not(a);
			break;

		case 2: // this = ~0:num
			RandBits(&a, BASEBITS);
			x2 = REFNOT(A_BASEINT);
			x1.Not(*(BASEINT*)&a);
			break;

		case 3: // this = ~int
			a = (BASEINT)123;
			x2 = REFNOT(A_REFINT);
			x1.Not((BASEINT)123);
			break;
		}
		break;

// --- AND &

	// cat=10
	case 10:
		op = (int)Rand(13);
		switch (op)
		{
		case 0: // this &= num
			RandBits(&a, TESTBITS);
			x2 = REFAND(x2, A_REFINT);
			x1.And(a);
			break;

		case 1: // this &= 0:num
			RandBits(&a, BASEBITS);
			x2 = REFAND(x2, A_BASEINT);
			x1.And(*(BASEINT*)&a);
			break;

		case 2: // this &= int
			a = (BASEINT)123;
			x2 = REFAND(x2, A_REFINT);
			x1.And((BASEINT)123);
			break;

		case 3: // this = num1 & num2
			RandBits(&a, TESTBITS);
			RandBits(&b, TESTBITS);
			x2 = REFAND(A_REFINT, B_REFINT);
			x1.And(a, b);
			break;

		case 4: // this = num1 & 0:num2
			RandBits(&a, TESTBITS);
			RandBits(&b, BASEBITS);
			x2 = REFAND(A_REFINT, B_BASEINT);
			x1.And(a, *(BASEINT*)&b);
			break;

		case 5: // this = 0:num1 & num2
			RandBits(&a, BASEBITS);
			RandBits(&b, TESTBITS);
			x2 = REFAND(A_BASEINT, B_REFINT);
			x1.And(*(BASEINT*)&a, b);
			break;

		case 6: // this = num1 & int
			RandBits(&a, TESTBITS);
			b = (BASEINT)123;
			x2 = REFAND(A_REFINT, B_REFINT);
			x1.And(a, (BASEINT)123);
			break;

		case 7: // this = int & num2
			a = (BASEINT)123;
			RandBits(&b, TESTBITS);
			x2 = REFAND(A_REFINT, B_REFINT);
			x1.And((BASEINT)123, b);
			break;

		case 8: // this = this & this
			RandBits(&a, TESTBITS);
			x2 = A_REFINT;
			x1 = a;
			x2 = REFAND(x2, x2);
			x1.And(x1, x1);
			break;

#ifdef DBLINT1
		case 9: // this &= 0:num
			RandBits(&a, DBLBITS);
			x2 = REFAND(x2, A_DBLINT);
			x1.And(*(DBLINT1*)&a);
			break;

		case 10: // this = num1 & 0:num2
			RandBits(&a, TESTBITS);
			RandBits(&b, DBLBITS);
			x2 = REFAND(A_REFINT, B_DBLINT);
			x1.And(a, *(DBLINT1*)&b);
			break;

		case 11: // this = 0:num1 & num2
			RandBits(&a, DBLBITS);
			RandBits(&b, TESTBITS);
			x2 = REFAND(A_DBLINT, B_REFINT);
			x1.And(*(DBLINT1*)&a, b);
			break;

		case 12: // this = this & 0:num2
			RandBits(&b, DBLBITS);
			x2 = REFAND(x2, B_DBLINT);
			x1.And(x1, *(DBLINT1*)&b);
			break;

		case 13: // this = 0:num1 & this
			RandBits(&a, DBLBITS);
			x2 = REFAND(A_DBLINT, x2);
			x1.And(*(DBLINT1*)&a, x1);
			break;
#endif // DBLINT1
		}
		break;

// --- OR |

	// cat=11
	case 11:
		op = (int)Rand(13);
		switch (op)
		{
		case 0: // this |= num
			RandBits(&a, TESTBITS);
			x2 = REFOR(x2, A_REFINT);
			x1.Or(a);
			break;

		case 1: // this |= 0:num
			RandBits(&a, BASEBITS);
			x2 = REFOR(x2, A_BASEINT);
			x1.Or(*(BASEINT*)&a);
			break;

		case 2: // this |= int
			a = (BASEINT)123;
			x2 = REFOR(x2, A_REFINT);
			x1.Or((BASEINT)123);
			break;

		case 3: // this = num1 | num2
			RandBits(&a, TESTBITS);
			RandBits(&b, TESTBITS);
			x2 = REFOR(A_REFINT, B_REFINT);
			x1.Or(a, b);
			break;

		case 4: // this = num1 | 0:num2
			RandBits(&a, TESTBITS);
			RandBits(&b, BASEBITS);
			x2 = REFOR(A_REFINT, B_BASEINT);
			x1.Or(a, *(BASEINT*)&b);
			break;

		case 5: // this = 0:num1 | num2
			RandBits(&a, BASEBITS);
			RandBits(&b, TESTBITS);
			x2 = REFOR(A_BASEINT, B_REFINT);
			x1.Or(*(BASEINT*)&a, b);
			break;

		case 6: // this = num1 | int
			RandBits(&a, TESTBITS);
			b = (BASEINT)123;
			x2 = REFOR(A_REFINT, B_REFINT);
			x1.Or(a, (BASEINT)123);
			break;

		case 7: // this = int | num2
			a = (BASEINT)123;
			RandBits(&b, TESTBITS);
			x2 = REFOR(A_REFINT, B_REFINT);
			x1.Or((BASEINT)123, b);
			break;

		case 8: // this = this | this
			RandBits(&a, TESTBITS);
			x2 = A_REFINT;
			x1 = a;
			x2 = REFOR(x2, x2);
			x1.Or(x1, x1);
			break;

#ifdef DBLINT1
		case 9: // this |= 0:num
			RandBits(&a, DBLBITS);
			x2 = REFOR(x2, A_DBLINT);
			x1.Or(*(DBLINT1*)&a);
			break;

		case 10: // this = num1 | 0:num2
			RandBits(&a, TESTBITS);
			RandBits(&b, DBLBITS);
			x2 = REFOR(A_REFINT, B_DBLINT);
			x1.Or(a, *(DBLINT1*)&b);
			break;

		case 11: // this = 0:num1 | num2
			RandBits(&a, DBLBITS);
			RandBits(&b, TESTBITS);
			x2 = REFOR(A_DBLINT, B_REFINT);
			x1.Or(*(DBLINT1*)&a, b);
			break;

		case 12: // this = this | 0:num2
			RandBits(&b, DBLBITS);
			x2 = REFOR(x2, B_DBLINT);
			x1.Or(x1, *(DBLINT1*)&b);
			break;

		case 13: // this = 0:num1 | this
			RandBits(&a, DBLBITS);
			x2 = REFOR(A_DBLINT, x2);
			x1.Or(*(DBLINT1*)&a, x1);
			break;
#endif // DBLINT1
		}
		break;

// --- XOR ^

	// cat=12
	case 12:
		op = (int)Rand(13);
		switch (op)
		{
		case 0: // this ^= num
			RandBits(&a, TESTBITS);
			x2 = REFXOR(x2, A_REFINT);
			x1.Xor(a);
			break;

		case 1: // this ^= 0:num
			RandBits(&a, BASEBITS);
			x2 = REFXOR(x2, A_BASEINT);
			x1.Xor(*(BASEINT*)&a);
			break;

		case 2: // this ^= int
			a = (BASEINT)123;
			x2 = REFXOR(x2, A_REFINT);
			x1.Xor((BASEINT)123);
			break;

		case 3: // this = num1 ^ num2
			RandBits(&a, TESTBITS);
			RandBits(&b, TESTBITS);
			x2 = REFXOR(A_REFINT, B_REFINT);
			x1.Xor(a, b);
			break;

		case 4: // this = num1 ^ 0:num2
			RandBits(&a, TESTBITS);
			RandBits(&b, BASEBITS);
			x2 = REFXOR(A_REFINT, B_BASEINT);
			x1.Xor(a, *(BASEINT*)&b);
			break;

		case 5: // this = 0:num1 ^ num2
			RandBits(&a, BASEBITS);
			RandBits(&b, TESTBITS);
			x2 = REFXOR(A_BASEINT, B_REFINT);
			x1.Xor(*(BASEINT*)&a, b);
			break;

		case 6: // this = num1 ^ int
			RandBits(&a, TESTBITS);
			b = (BASEINT)123;
			x2 = REFXOR(A_REFINT, B_REFINT);
			x1.Xor(a, (BASEINT)123);
			break;

		case 7: // this = int ^ num2
			a = (BASEINT)123;
			RandBits(&b, TESTBITS);
			x2 = REFXOR(A_REFINT, B_REFINT);
			x1.Xor((BASEINT)123, b);
			break;

		case 8: // this = this ^ this
			RandBits(&a, TESTBITS);
			x2 = A_REFINT;
			x1 = a;
			x2 = REFXOR(x2, x2);
			x1.Xor(x1, x1);
			break;

#ifdef DBLINT1
		case 9: // this ^= 0:num
			RandBits(&a, DBLBITS);
			x2 = REFXOR(x2, A_DBLINT);
			x1.Xor(*(DBLINT1*)&a);
			break;

		case 10: // this = num1 ^ 0:num2
			RandBits(&a, TESTBITS);
			RandBits(&b, DBLBITS);
			x2 = REFXOR(A_REFINT, B_DBLINT);
			x1.Xor(a, *(DBLINT1*)&b);
			break;

		case 11: // this = 0:num1 ^ num2
			RandBits(&a, DBLBITS);
			RandBits(&b, TESTBITS);
			x2 = REFXOR(A_DBLINT, B_REFINT);
			x1.Xor(*(DBLINT1*)&a, b);
			break;

		case 12: // this = this ^ 0:num2
			RandBits(&b, DBLBITS);
			x2 = REFXOR(x2, B_DBLINT);
			x1.Xor(x1, *(DBLINT1*)&b);
			break;

		case 13: // this = 0:num1 ^ this
			RandBits(&a, DBLBITS);
			x2 = REFXOR(A_DBLINT, x2);
			x1.Xor(*(DBLINT1*)&a, x1);
			break;
#endif // DBLINT1
		}
		break;

// --- set/clear/get bit

	// cat=13
	case 13:
		op = (int)Rand(5);
		switch (op)
		{
		case 0: // set bit
			shift = (int)Rand(TESTBITS-1);
			a.Set0();
			a.N0() = (BASEINT)1;
			a.LShift(shift);
			x2 = REFOR(x2, A_REFINT);
			x1.SetBit(shift);
			break;

		case 1: // reset bit
			shift = (int)Rand(TESTBITS-1);
			a.Set0();
			a.N0() = (BASEINT)1;
			a.LShift(shift);
			x2 = REFAND(x2, REFNOT(A_REFINT));
			x1.ResBit(shift);
			break;

		case 2: // flip bit
			shift = (int)Rand(TESTBITS-1);
			a.Set0();
			a.N0() = (BASEINT)1;
			a.LShift(shift);
			x2 = REFXOR(x2, A_REFINT);
			x1.FlipBit(shift);
			break;

		case 3: // get bit
			RandBits(&a, TESTBITS);
			shift = (int)Rand(TESTBITS-1);
			x1 = (BASEINT)a.GetBit(shift);
			b = a;
			b >>= shift;
			b = (BASEINT)(b.N0() & 1);
			x2 = B_REFINT;
			b = (BASEINT)shift;
			break;

#ifndef FIXED
		case 4: // number of bits
			RandBits(&a, TESTBITS);
			x2 = A_REFINT;
#ifdef SIGNED
			if (x2 < 0)
			{
				x2 = -x2;
				if (x2 < 0) x2--; // overflow 0x8000 -> 0x7fff
			}
#endif // SIGNED
			shift = 0;
			while (x2 != 0)
			{
				shift++;
				x2 >>= 1;
			}
			b = (BASEINT)shift;
			x2 = B_REFINT;
			x1 = (BASEINT)a.Bits();
			break;

		case 5: // check power of 2
			RandBits(&a, TESTBITS);
			x2 = A_REFINT;
#ifdef SIGNED
			if (x2 < 0)
			{
				x2 = -x2;
				if (x2 < 0) x2--; // overflow 0x8000 -> 0x7fff
			}
#endif // SIGNED
			if (x2 != 0)
			{
				while ((x2 & (BASEINT)1) == 0) x2 >>= 1;
				if (x2 != (BASEINT)1) x2 = 0;
			}
			x1 = (BASEINT)(a.IsPwr2() ? 1 : 0);
			break;
#endif // FIXED
		}
		break;

// --- shift << >>

	// cat=14
	case 14:
		op = (int)Rand(17);
		switch (op)
		{
		case 0: // this <<= 1
			RandBits(&a, TESTBITS);
			x2 = REFSHL(A_REFINT, 1);
			x1 = a;
			x1.LShift1();
			break;

		case 1: // this <<= shift
			RandBits(&a, TESTBITS);
			shift = (int)Rand(TESTBITS-1);
			x2 = REFSHL(A_REFINT, shift);
			x1 = a;
			x1.LShift(shift);
			b = (BASEINT)shift;
			break;

		case 2: // this <<= int
			RandBits(&a, TESTBITS);
			x2 = REFSHL(A_REFINT, 12);
			x1 = a;
			x1.LShift(12);
			break;

		case 3: // this = num << 1
			RandBits(&a, TESTBITS);
			x2 = REFSHL(A_REFINT, 1);
			x1.LShift1(a);
			break;

		case 4: // this = num << shift
			RandBits(&a, TESTBITS);
			shift = (int)Rand(TESTBITS-1);
			x2 = REFSHL(A_REFINT, shift);
			x1.LShift(a, shift);
			b = (BASEINT)shift;
			break;

		case 5: // this = num << int
			RandBits(&a, TESTBITS);
			x2 = REFSHL(A_REFINT, 12);
			x1.LShift(a, 12);
			break;

		case 6: // this = 0:num << 1
			RandBits(&a, BASEBITS);
			x2 = REFSHL(A_BASEINT, 1);
			x1.LShift1(*(BASEINT*)&a);
			break;

		case 7: // this = 0:num << shift
			RandBits(&a, BASEBITS);
			shift = (int)Rand(TESTBITS-1);
			x2 = REFSHL(A_BASEINT, shift);
			x1.LShift(*(BASEINT*)&a, shift);
			b = (BASEINT)shift;
			break;

		case 8: // this = int << shift
			a = (BASEINT)123;
			shift = (int)Rand(TESTBITS-1);
			x2 = REFSHL(A_REFINT, shift);
			x1.LShift((BASEINT)123, shift);
			b = (BASEINT)shift;
			break;

		case 9: // this >>= 1
			RandBits(&a, TESTBITS);
			x2 = REFSHR(A_REFINT, 1);
			x1 = a;
			x1.RShift1();
			break;

		case 10: // this >>= shift
			RandBits(&a, TESTBITS);
			shift = (int)Rand(TESTBITS-1);
			x2 = REFSHR(A_REFINT, shift);
			x1 = a;
			x1.RShift(shift);
			b = (BASEINT)shift;
			break;

		case 11: // this >>= int
			RandBits(&a, TESTBITS);
			x2 = REFSHR(A_REFINT, 12);
			x1 = a;
			x1.RShift(12);
			break;

		case 12: // this = num >> 1
			RandBits(&a, TESTBITS);
			x2 = REFSHR(A_REFINT, 1);
			x1.RShift1(a);
			break;

		case 13: // this = num >> shift
			RandBits(&a, TESTBITS);
			shift = (int)Rand(TESTBITS-1);
			x2 = REFSHR(A_REFINT, shift);
			x1.RShift(a, shift);
			b = (BASEINT)shift;
			break;

		case 14: // this = num >> int
			RandBits(&a, TESTBITS);
			x2 = REFSHR(A_REFINT, 12);
			x1.RShift(a, 12);
			break;

		case 15: // this = 0:num >> 1
			RandBits(&a, BASEBITS);
			x2 = REFSHR(A_BASEINT, 1);
			x1.RShift1(*(BASEINT*)&a);
			break;

		case 16: // this = 0:num >> shift
			RandBits(&a, BASEBITS);
			shift = (int)Rand(TESTBITS-1);
			x2 = REFSHR(A_BASEINT, shift);
			x1.RShift(*(BASEINT*)&a, shift);
			b = (BASEINT)shift;
			break;

		case 17: // this = int >> shift
			a = (BASEINT)123;
			shift = (int)Rand(TESTBITS-1);
			x2 = REFSHR(A_REFINT, shift);
			x1.RShift((BASEINT)123, shift);
			b = (BASEINT)shift;
			break;
		}
		break;

// --- text conversion

	// cat=15
	case 15:
		op = 0;
		{
			RandBits(&a, TESTBITS);
			x2 = A_REFINT;
			a.ToText(TextBuf, TEXTBUF_SIZE);
			x1.FromText(TextBuf);
#ifdef FIXED
			{ // rounding error is OK
				REFINT k = *(REFINT*)&x1 - *(REFINT*)&x2;
				if (k < 0) k = -k;
				if (k <= 5) x1 = a;
			}
#endif
		}
		break;

// --- "in class" operators

	// cat=16
	case 16:
		op = (int)Rand(43);
		switch (op)
		{
		case 0: // this = num
			RandBits(&a, TESTBITS);
			x2 = A_REFINT;
			x1 = a;
			break;

		case 1: // this = this
			x2 = x2;
			x1 = x1;
			break;

		case 2: // this = 0:num
			RandBits(&a, BASEBITS);
			x2 = A_BASEINT;
			x1 = *(BASEINT*)&a;
			break;

		case 3: // this = int
			a = (BASEINT)123;
			x2 = A_REFINT;
			x1 = (BASEINT)123;
			break;

		case 4: // this += num
			RandBits(&a, TESTBITS);
			x2 = REFADD(x2, A_REFINT);
			x1 += a;
			break;

		case 5: // this += this
			x2 = REFADD(x2, x2);
			x1 += x1;
			break;

		case 6: // this += 0:num
			RandBits(&a, BASEBITS);
			x2 = REFADD(x2, A_BASEINT);
			x1 += *(BASEINT*)&a;
			break;

		case 7: // this += int
			a = (BASEINT)123;
			x2 = REFADD(x2, A_REFINT);
			x1 += (BASEINT)123;
			break;

		case 8: // this -= num
			RandBits(&a, TESTBITS);
			x2 = REFSUB(x2, A_REFINT);
			x1 -= a;
			break;

		case 9: // this -= this
			x2 = REFSUB(x2, x2);
			x1 -= x1;
			break;

		case 10: // this -= 0:num
			RandBits(&a, BASEBITS);
			x2 = REFSUB(x2, A_BASEINT);
			x1 -= *(BASEINT*)&a;
			break;

		case 11: // this -= int
			a = (BASEINT)123;
			x2 = REFSUB(x2, A_REFINT);
			x1 -= (BASEINT)123;
			break;

		case 12: // this++
			x2 = REFINC(x2);
			x1++;
			break;

		case 13: // ++this
			x2 = REFINC(x2);
			++x1;
			break;

		case 14: // this = num++
			RandBits(&a, TESTBITS);
			b = a;
			x2 = A_REFINT;
			a = a + (BASEINT)1;
			x1 = b++;
			break;

		case 15: // this = ++num
			RandBits(&a, TESTBITS);
			b = a;
			a = a + (BASEINT)1;
			x2 = A_REFINT;
			x1 = ++b;
			break;

		case 16: // this--
			x2 = REFDEC(x2);
			x1--;
			break;

		case 17: // --this
			x2 = REFDEC(x2);
			--x1;
			break;

		case 18: // this = num--
			RandBits(&a, TESTBITS);
			b = a;
			x2 = A_REFINT;
			a = a - (BASEINT)1;
			x1 = b--;
			break;

		case 19: // this = --num
			RandBits(&a, TESTBITS);
			b = a;
			a = a - (BASEINT)1;
			x2 = A_REFINT;
			x1 = --b;
			break;

		case 20: // this = -num
			RandBits(&a, TESTBITS);
			x2 = -A_REFINT;
			x1 = -a;
			break;

		case 21: // this = -num, to verify that source is not modified
			RandBits(&a, TESTBITS);
			x1 = -a;
			x2 = -A_REFINT;
			break;

		case 22: // this *= num
			RandBits(&a, TESTBITS);
			x2 = REFMUL(x2, A_REFINT);
			x1 *= a;
			break;

		case 23: // this *= this
			x2 = REFMUL(x2, x2);
			x1 *= x1;
			break;

		case 24: // this *= 0:num
			RandBits(&a, BASEBITS);
			x2 = REFMUL(x2, A_BASEINT);
			x1 *= *(BASEINT*)&a;
			break;

		case 25: // this *= int
			a = (BASEINT)123;
			x2 = REFMUL(x2, A_REFINT);
			x1 *= (BASEINT)123;
			break;

		case 26: // this = ~num
			RandBits(&a, TESTBITS);
			x2 = REFNOT(A_REFINT);
			x1 = ~a;
			break;

		case 27: // this = ~num, to verify that source is not modified
			RandBits(&a, TESTBITS);
			x1 = ~a;
			x2 = REFNOT(A_REFINT);
			break;

		case 28: // this &= num
			RandBits(&a, TESTBITS);
			x2 = REFAND(x2, A_REFINT);
			x1 &= a;
			break;

		case 29: // this &= this
			x2 = REFAND(x2, x2);
			x1 &= x1;
			break;

		case 30: // this &= 0:num
			RandBits(&a, BASEBITS);
			x2 = REFAND(x2, A_BASEINT);
			x1 &= *(BASEINT*)&a;
			break;

		case 31: // this &= int
			a = (BASEINT)123;
			x2 = REFAND(x2, A_REFINT);
			x1 &= (BASEINT)123;
			break;

		case 32: // this |= num
			RandBits(&a, TESTBITS);
			x2 = REFOR(x2, A_REFINT);
			x1 |= a;
			break;

		case 33: // this |= this
			x2 = REFOR(x2, x2);
			x1 |= x1;
			break;

		case 34: // this |= 0:num
			RandBits(&a, BASEBITS);
			x2 = REFOR(x2, A_BASEINT);
			x1 |= *(BASEINT*)&a;
			break;

		case 35: // this |= int
			a = (BASEINT)123;
			x2 = REFOR(x2, A_REFINT);
			x1 |= (BASEINT)123;
			break;

		case 36: // this ^= num
			RandBits(&a, TESTBITS);
			x2 = REFXOR(x2, A_REFINT);
			x1 ^= a;
			break;

		case 37: // this ^= this
			x2 = REFXOR(x2, x2);
			x1 ^= x1;
			break;

		case 38: // this ^= 0:num
			RandBits(&a, BASEBITS);
			x2 = REFXOR(x2, A_BASEINT);
			x1 ^= *(BASEINT*)&a;
			break;

		case 39: // this ^= int
			a = (BASEINT)123;
			x2 = REFXOR(x2, A_REFINT);
			x1 ^= (BASEINT)123;
			break;

		case 40: // this <<= shift
			RandBits(&a, TESTBITS);
			shift = (int)Rand(TESTBITS-1);
			x2 = REFSHL(A_REFINT, shift);
			x1 = a;
			x1 <<= shift;
			break;

		case 41: // this <<= int
			RandBits(&a, TESTBITS);
			x2 = REFSHL(A_REFINT, 12);
			x1 = a;
			x1 <<= 12;
			break;

		case 42: // this >>= shift
			RandBits(&a, TESTBITS);
			shift = (int)Rand(TESTBITS-1);
			x2 = REFSHR(A_REFINT, shift);
			x1 = a;
			x1 >>= shift;
			break;

		case 43: // this >>= int
			RandBits(&a, TESTBITS);
			x2 = REFSHR(A_REFINT, 12);
			x1 = a;
			x1 >>= 12;
			break;
		}
		break;

// --- + operator

	// cat=17
	case 17:
		op = (int)Rand(9);
		switch (op)
		{
		case 0: // this = num1 + num2
			RandBits(&a, TESTBITS);
			RandBits(&b, TESTBITS);
			x2 = REFADD(A_REFINT, B_REFINT);
			x1 = a + b;
			break;

		case 1: // this = this + num2
			RandBits(&a, TESTBITS);
			x2 = REFADD(x2, A_REFINT);
			x1 = x1 + a;
			break;

		case 2: // this = num1 + this
			RandBits(&a, TESTBITS);
			x2 = REFADD(A_REFINT, x2);
			x1 = a + x1;
			break;

		case 3: // this = num1 + 0:num2
			RandBits(&a, TESTBITS);
			RandBits(&b, BASEBITS);
			x2 = REFADD(A_REFINT, B_BASEINT);
			x1 = a + *(BASEINT*)&b;
			break;

		case 4: // this = 0:num1 + num2
			RandBits(&a, BASEBITS);
			RandBits(&b, TESTBITS);
			x2 = REFADD(A_BASEINT, B_REFINT);
			x1 = *(BASEINT*)&a + b;
			break;

		case 5: // this = this + 0:num2
			RandBits(&b, BASEBITS);
			x2 = REFADD(x2, B_BASEINT);
			x1 = x1 + *(BASEINT*)&b;
			break;

		case 6: // this = 0:num1 + this
			RandBits(&a, BASEBITS);
			x2 = REFADD(A_BASEINT, x2);
			x1 = *(BASEINT*)&a + x1;
			break;

		case 7: // this = num1 + int
			RandBits(&a, TESTBITS);
			b = (BASEINT)123;
			x2 = REFADD(A_REFINT, B_REFINT);
			x1 = a + (BASEINT)123;
			break;

		case 8: // this = int + num2
			a = (BASEINT)123;
			RandBits(&b, TESTBITS);
			x2 = REFADD(A_REFINT, B_REFINT);
			x1 = (BASEINT)123 + b;
			break;

		case 9: // this = this + this
			RandBits(&a, TESTBITS);
			x2 = A_REFINT;
			x1 = a;
			x2 = REFADD(x2, x2);
			x1 = x1 + x1;
			break;
		}
		break;

// --- - operator

	// cat=18
	case 18:
		op = (int)Rand(9);
		switch (op)
		{
		case 0: // this = num1 - num2
			RandBits(&a, TESTBITS);
			RandBits(&b, TESTBITS);
			x2 = REFSUB(A_REFINT, B_REFINT);
			x1 = a - b;
			break;

		case 1: // this = this - num2
			RandBits(&a, TESTBITS);
			x2 = REFSUB(x2, A_REFINT);
			x1 = x1 - a;
			break;

		case 2: // this = num1 - this
			RandBits(&a, TESTBITS);
			x2 = REFSUB(A_REFINT, x2);
			x1 = a - x1;
			break;

		case 3: // this = num1 - 0:num2
			RandBits(&a, TESTBITS);
			RandBits(&b, BASEBITS);
			x2 = REFSUB(A_REFINT, B_BASEINT);
			x1 = a - *(BASEINT*)&b;
			break;

		case 4: // this = 0:num1 - num2
			RandBits(&a, BASEBITS);
			RandBits(&b, TESTBITS);
			x2 = REFSUB(A_BASEINT, B_REFINT);
			x1 = *(BASEINT*)&a - b;
			break;

		case 5: // this = this - 0:num2
			RandBits(&b, BASEBITS);
			x2 = REFSUB(x2, B_BASEINT);
			x1 = x1 - *(BASEINT*)&b;
			break;

		case 6: // this = 0:num1 - this
			RandBits(&a, BASEBITS);
			x2 = REFSUB(A_BASEINT, x2);
			x1 = *(BASEINT*)&a - x1;
			break;

		case 7: // this = num1 - int
			RandBits(&a, TESTBITS);
			b = (BASEINT)123;
			x2 = REFSUB(A_REFINT, B_REFINT);
			x1 = a - (BASEINT)123;
			break;

		case 8: // this = int - num2
			a = (BASEINT)123;
			RandBits(&b, TESTBITS);
			x2 = REFSUB(A_REFINT, B_REFINT);
			x1 = (BASEINT)123 - b;
			break;

		case 9: // this = this - this
			RandBits(&a, TESTBITS);
			x2 = A_REFINT;
			x1 = a;
			x2 = REFSUB(x2, x2);
			x1 = x1 - x1;
			break;
		}
		break;

// --- * operator

	// cat=19
	case 19:
		op = (int)Rand(9);
		switch (op)
		{
		case 0: // this = num1 * num2
			RandBits(&a, TESTBITS);
			RandBits(&b, TESTBITS);
			x2 = REFMUL(A_REFINT, B_REFINT);
			x1 = a * b;
			break;

		case 1: // this = this * num2
			RandBits(&a, TESTBITS);
			x2 = REFMUL(x2, A_REFINT);
			x1 = x1 * a;
			break;

		case 2: // this = num1 * this
			RandBits(&a, TESTBITS);
			x2 = REFMUL(A_REFINT, x2);
			x1 = a * x1;
			break;

		case 3: // this = num1 * 0:num2
			RandBits(&a, TESTBITS);
			RandBits(&b, BASEBITS);
			x2 = REFMUL(A_REFINT, B_BASEINT);
			x1 = a * *(BASEINT*)&b;
			break;

		case 4: // this = 0:num1 * num2
			RandBits(&a, BASEBITS);
			RandBits(&b, TESTBITS);
			x2 = REFMUL(A_BASEINT, B_REFINT);
			x1 = *(BASEINT*)&a * b;
			break;

		case 5: // this = this * 0:num2
			RandBits(&b, BASEBITS);
			x2 = REFMUL(x2, B_BASEINT);
			x1 = x1 * *(BASEINT*)&b;
			break;

		case 6: // this = 0:num1 * this
			RandBits(&a, BASEBITS);
			x2 = REFMUL(A_BASEINT, x2);
			x1 = *(BASEINT*)&a * x1;
			break;

		case 7: // this = num1 * int
			RandBits(&a, TESTBITS);
			b = (BASEINT)123;
			x2 = REFMUL(A_REFINT, B_REFINT);
			x1 = a * (BASEINT)123;
			break;

		case 8: // this = int * num2
			a = (BASEINT)123;
			RandBits(&b, TESTBITS);
			x2 = REFMUL(A_REFINT, B_REFINT);
			x1 = (BASEINT)123 * b;
			break;

		case 9: // this = this * this
			x2 = REFMUL(x2, x2);
			x1 = x1 * x1;
			break;
		}
		break;

// --- / and % operator

	// cat=20
	case 20:
		op = (int)Rand(7);
		switch (op)
		{
		case 0: // this = num1 / num2
			RandBits(&a, TESTBITS);
			RandBits(&b, TESTBITS);
			if (b.Equ0()) b.Set1();
			x2 = REFDIV(A_REFINT, B_REFINT);
			x1 = a / b;
			break;

		case 1: // this = num1 % num2
			RandBits(&a, TESTBITS);
			RandBits(&b, TESTBITS);
			if (b.Equ0()) b.Set1();
			x2 = REFMOD(A_REFINT, B_REFINT);
			x1 = a % b;
			break;

		case 2: // this = num1 / 0:0:0:num2, returns remainder
			RandBits(&a, TESTBITS);
			RandBits(&b, HALFBITS);
			*(BASEINT*)&b = *(HALFINT*)&b;
			if (*(BASEINT*)&b == (BASEINT)0) *(BASEINT*)&b = (BASEINT)1;
			x2 = REFDIV(A_REFINT, B_BASEINT); // HALFINT is ambiquous
			x1 = a / *(HALFINT*)&b;
			break;

		case 3: // this = num1 % 0:0:0:num2, returns remainder
			RandBits(&a, TESTBITS);
			RandBits(&b, HALFBITS);
			*(BASEINT*)&b = *(HALFINT*)&b;
			if (*(BASEINT*)&b == (BASEINT)0) *(BASEINT*)&b = (BASEINT)1;
			x2 = REFMOD(A_REFINT, B_BASEINT); // HALFINT is ambiquous
			x1 = a % *(HALFINT*)&b;
			break;

		case 4: // this = num1 / 0:num2, returns remainder
			RandBits(&a, TESTBITS);
			RandBits(&b, BASEBITS);
			if (*(BASEINT*)&b == (BASEINT)0) *(BASEINT*)&b = (BASEINT)1;
			x2 = REFDIV(A_REFINT, B_BASEINT);
			x1 = a / *(BASEINT*)&b;
			break;

		case 5: // this = num1 % 0:num2, returns remainder
			RandBits(&a, TESTBITS);
			RandBits(&b, BASEBITS);
			if (*(BASEINT*)&b == (BASEINT)0) *(BASEINT*)&b = (BASEINT)1;
			x2 = REFMOD(A_REFINT, B_BASEINT);
			x1 = a % *(BASEINT*)&b;
			break;

#ifdef DBLINT1
		case 6: // this = num1 / 0:num2
			RandBits(&a, TESTBITS);
			RandBits(&b, DBLBITS);
			if (*(DBLINT1*)&b == (BASEINT)0) *(DBLINT1*)&b = (BASEINT)1;
			x2 = REFDIV(A_REFINT, B_DBLINT);
			x1 = a / *(DBLINT1*)&b;
			break;

		case 7: // this = num1 % 0:num2
			RandBits(&a, TESTBITS);
			RandBits(&b, DBLBITS);
			if (*(DBLINT1*)&b == (BASEINT)0) *(DBLINT1*)&b = (BASEINT)1;
			x2 = REFMOD(A_REFINT, B_DBLINT);
			x1 = a % *(DBLINT1*)&b;
			break;
#endif // DBLINT1
		}
		break;

// --- comparison operators

	// cat=21
	case 21:
		op = (int)Rand(29);
		switch (op)
		{
		case 0: // num1 == num2
			RandBits(&a, TESTBITS);
			RandBits(&b, TESTBITS);
			x2 = REFCMP(A_REFINT == B_REFINT);
			x1 = (BASEINT)((a == b) ? 1 : 0);
			break;

		case 1: // num1 == 0:num2
			RandBits(&a, TESTBITS);
			RandBits(&b, BASEBITS);
			x2 = REFCMP(A_REFINT == B_BASEINT);
			x1 = (BASEINT)((a == *(BASEINT*)&b) ? 1 : 0);
			break;

		case 2: // 0:num1 == num2
			RandBits(&a, BASEBITS);
			RandBits(&b, TESTBITS);
			x2 = REFCMP(A_BASEINT == B_REFINT);
			x1 = (BASEINT)((*(BASEINT*)&a == b) ? 1 : 0);
			break;

		case 3: // num == int
			RandBits(&a, TESTBITS);
			b = (BASEINT)123;
			x2 = REFCMP(A_REFINT == B_REFINT);
			x1 = (BASEINT)((a == (BASEINT)123) ? 1 : 0);
			break;

		case 4: // int == num
			a = (BASEINT)123;
			RandBits(&b, TESTBITS);
			x2 = REFCMP(A_REFINT == B_REFINT);
			x1 = (BASEINT)(((BASEINT)123 == b) ? 1 : 0);
			break;

		case 5: // num1 != num2
			RandBits(&a, TESTBITS);
			RandBits(&b, TESTBITS);
			x2 = REFCMP(A_REFINT != B_REFINT);
			x1 = (BASEINT)((a != b) ? 1 : 0);
			break;

		case 6: // num1 != 0:num2
			RandBits(&a, TESTBITS);
			RandBits(&b, BASEBITS);
			x2 = REFCMP(A_REFINT != B_BASEINT);
			x1 = (BASEINT)((a != *(BASEINT*)&b) ? 1 : 0);
			break;

		case 7: // 0:num1 != num2
			RandBits(&a, BASEBITS);
			RandBits(&b, TESTBITS);
			x2 = REFCMP(A_BASEINT != B_REFINT);
			x1 = (BASEINT)((*(BASEINT*)&a != b) ? 1 : 0);
			break;

		case 8: // num != int
			RandBits(&a, TESTBITS);
			b = (BASEINT)123;
			x2 = REFCMP(A_REFINT != B_REFINT);
			x1 = (BASEINT)((a != (BASEINT)123) ? 1 : 0);
			break;

		case 9: // int != num
			a = (BASEINT)123;
			RandBits(&b, TESTBITS);
			x2 = REFCMP(A_REFINT != B_REFINT);
			x1 = (BASEINT)(((BASEINT)123 != b) ? 1 : 0);
			break;
 
		case 10: // num1 < num2
			RandBits(&a, TESTBITS);
			RandBits(&b, TESTBITS);
			x2 = REFCMP(A_REFINT < B_REFINT);
			x1 = (BASEINT)((a < b) ? 1 : 0);
			break;

		case 11: // num1 < 0:num2
			RandBits(&a, TESTBITS);
			RandBits(&b, BASEBITS);
			x2 = REFCMP(A_REFINT < B_BASEINT);
			x1 = (BASEINT)((a < *(BASEINT*)&b) ? 1 : 0);
			break;

		case 12: // 0:num1 < num2
			RandBits(&a, BASEBITS);
			RandBits(&b, TESTBITS);
			x2 = REFCMP(A_BASEINT < B_REFINT);
			x1 = (BASEINT)((*(BASEINT*)&a < b) ? 1 : 0);
			break;

		case 13: // num < int
			RandBits(&a, TESTBITS);
			b = (BASEINT)123;
			x2 = REFCMP(A_REFINT < B_REFINT);
			x1 = (BASEINT)((a < (BASEINT)123) ? 1 : 0);
			break;

		case 14: // int < num
			a = (BASEINT)123;
			RandBits(&b, TESTBITS);
			x2 = REFCMP(A_REFINT < B_REFINT);
			x1 = (BASEINT)(((BASEINT)123 < b) ? 1 : 0);
			break;

		case 15: // num1 <= num2
			RandBits(&a, TESTBITS);
			RandBits(&b, TESTBITS);
			x2 = REFCMP(A_REFINT <= B_REFINT);
			x1 = (BASEINT)((a <= b) ? 1 : 0);
			break;

		case 16: // num1 <= 0:num2
			RandBits(&a, TESTBITS);
			RandBits(&b, BASEBITS);
			x2 = REFCMP(A_REFINT <= B_BASEINT);
			x1 = (BASEINT)((a <= *(BASEINT*)&b) ? 1 : 0);
			break;

		case 17: // 0:num1 <= num2
			RandBits(&a, BASEBITS);
			RandBits(&b, TESTBITS);
			x2 = REFCMP(A_BASEINT <= B_REFINT);
			x1 = (BASEINT)((*(BASEINT*)&a <= b) ? 1 : 0);
			break;

		case 18: // num <= int
			RandBits(&a, TESTBITS);
			b = (BASEINT)123;
			x2 = REFCMP(A_REFINT <= B_REFINT);
			x1 = (BASEINT)((a <= (BASEINT)123) ? 1 : 0);
			break;

		case 19: // int <= num
			a = (BASEINT)123;
			RandBits(&b, TESTBITS);
			x2 = REFCMP(A_REFINT <= B_REFINT);
			x1 = (BASEINT)(((BASEINT)123 <= b) ? 1 : 0);
			break;

		case 20: // num1 > num2
			RandBits(&a, TESTBITS);
			RandBits(&b, TESTBITS);
			x2 = REFCMP(A_REFINT > B_REFINT);
			x1 = (BASEINT)((a > b) ? 1 : 0);
			break;

		case 21: // num1 > 0:num2
			RandBits(&a, TESTBITS);
			RandBits(&b, BASEBITS);
			x2 = REFCMP(A_REFINT > B_BASEINT);
			x1 = (BASEINT)((a > *(BASEINT*)&b) ? 1 : 0);
			break;

		case 22: // 0:num1 > num2
			RandBits(&a, BASEBITS);
			RandBits(&b, TESTBITS);
			x2 = REFCMP(A_BASEINT > B_REFINT);
			x1 = (BASEINT)((*(BASEINT*)&a > b) ? 1 : 0);
			break;

		case 23: // num > int
			RandBits(&a, TESTBITS);
			b = (BASEINT)123;
			x2 = REFCMP(A_REFINT > B_REFINT);
			x1 = (BASEINT)((a > (BASEINT)123) ? 1 : 0);
			break;

		case 24: // int > num
			a = (BASEINT)123;
			RandBits(&b, TESTBITS);
			x2 = REFCMP(A_REFINT > B_REFINT);
			x1 = (BASEINT)(((BASEINT)123 > b) ? 1 : 0);
			break;

		case 25: // num1 >= num2
			RandBits(&a, TESTBITS);
			RandBits(&b, TESTBITS);
			x2 = REFCMP(A_REFINT >= B_REFINT);
			x1 = (BASEINT)((a >= b) ? 1 : 0);
			break;

		case 26: // num1 >= 0:num2
			RandBits(&a, TESTBITS);
			RandBits(&b, BASEBITS);
			x2 = REFCMP(A_REFINT >= B_BASEINT);
			x1 = (BASEINT)((a >= *(BASEINT*)&b) ? 1 : 0);
			break;

		case 27: // 0:num1 >= num2
			RandBits(&a, BASEBITS);
			RandBits(&b, TESTBITS);
			x2 = REFCMP(A_BASEINT >= B_REFINT);
			x1 = (BASEINT)((*(BASEINT*)&a >= b) ? 1 : 0);
			break;

		case 28: // num >= int
			RandBits(&a, TESTBITS);
			b = (BASEINT)123;
			x2 = REFCMP(A_REFINT >= B_REFINT);
			x1 = (BASEINT)((a >= (BASEINT)123) ? 1 : 0);
			break;

		case 29: // int >= num
			a = (BASEINT)123;
			RandBits(&b, TESTBITS);
			x2 = REFCMP(A_REFINT >= B_REFINT);
			x1 = (BASEINT)(((BASEINT)123 >= b) ? 1 : 0);
			break;
		}
		break;

// --- & operator

	// cat=22
	case 22:
		op = (int)Rand(9);
		switch (op)
		{
		case 0: // this = num1 & num2
			RandBits(&a, TESTBITS);
			RandBits(&b, TESTBITS);
			x2 = REFAND(A_REFINT, B_REFINT);
			x1 = a & b;
			break;

		case 1: // this = this & num2
			RandBits(&a, TESTBITS);
			x2 = REFAND(x2, A_REFINT);
			x1 = x1 & a;
			break;

		case 2: // this = num1 & this
			RandBits(&a, TESTBITS);
			x2 = REFAND(A_REFINT, x2);
			x1 = a & x1;
			break;

		case 3: // this = num1 & 0:num2
			RandBits(&a, TESTBITS);
			RandBits(&b, BASEBITS);
			x2 = REFAND(A_REFINT, B_BASEINT);
			x1 = a & *(BASEINT*)&b;
			break;

		case 4: // this = 0:num1 & num2
			RandBits(&a, BASEBITS);
			RandBits(&b, TESTBITS);
			x2 = REFAND(A_BASEINT, B_REFINT);
			x1 = *(BASEINT*)&a & b;
			break;

		case 5: // this = this & 0:num2
			RandBits(&b, BASEBITS);
			x2 = REFAND(x2, B_BASEINT);
			x1 = x1 & *(BASEINT*)&b;
			break;

		case 6: // this = 0:num1 & this
			RandBits(&a, BASEBITS);
			x2 = REFAND(A_BASEINT, x2);
			x1 = *(BASEINT*)&a & x1;
			break;

		case 7: // this = num1 & int
			RandBits(&a, TESTBITS);
			b = (BASEINT)123;
			x2 = REFAND(A_REFINT, B_REFINT);
			x1 = a & (BASEINT)123;
			break;

		case 8: // this = int & num2
			a = (BASEINT)123;
			RandBits(&b, TESTBITS);
			x2 = REFAND(A_REFINT, B_REFINT);
			x1 = (BASEINT)123 & b;
			break;

		case 9: // this = this & this
			RandBits(&a, TESTBITS);
			x2 = A_REFINT;
			x1 = a;
			x2 = REFAND(x2, x2);
			x1 = x1 & x1;
			break;
		}
		break;

// --- | operator

	// cat=23
	case 23:
		op = (int)Rand(9);
		switch (op)
		{
		case 0: // this = num1 | num2
			RandBits(&a, TESTBITS);
			RandBits(&b, TESTBITS);
			x2 = REFOR(A_REFINT, B_REFINT);
			x1 = a | b;
			break;

		case 1: // this = this | num2
			RandBits(&a, TESTBITS);
			x2 = REFOR(x2, A_REFINT);
			x1 = x1 | a;
			break;

		case 2: // this = num1 | this
			RandBits(&a, TESTBITS);
			x2 = REFOR(A_REFINT, x2);
			x1 = a | x1;
			break;

		case 3: // this = num1 | 0:num2
			RandBits(&a, TESTBITS);
			RandBits(&b, BASEBITS);
			x2 = REFOR(A_REFINT, B_BASEINT);
			x1 = a | *(BASEINT*)&b;
			break;

		case 4: // this = 0:num1 | num2
			RandBits(&a, BASEBITS);
			RandBits(&b, TESTBITS);
			x2 = REFOR(A_BASEINT, B_REFINT);
			x1 = *(BASEINT*)&a | b;
			break;

		case 5: // this = this | 0:num2
			RandBits(&b, BASEBITS);
			x2 = REFOR(x2, B_BASEINT);
			x1 = x1 | *(BASEINT*)&b;
			break;

		case 6: // this = 0:num1 | this
			RandBits(&a, BASEBITS);
			x2 = REFOR(A_BASEINT, x2);
			x1 = *(BASEINT*)&a | x1;
			break;

		case 7: // this = num1 | int
			RandBits(&a, TESTBITS);
			b = (BASEINT)123;
			x2 = REFOR(A_REFINT, B_REFINT);
			x1 = a | (BASEINT)123;
			break;

		case 8: // this = int | num2
			a = (BASEINT)123;
			RandBits(&b, TESTBITS);
			x2 = REFOR(A_REFINT, B_REFINT);
			x1 = (BASEINT)123 | b;
			break;

		case 9: // this = this | this
			RandBits(&a, TESTBITS);
			x2 = A_REFINT;
			x1 = a;
			x2 = REFOR(x2, x2);
			x1 = x1 | x1;
			break;
		}
		break;

// --- ^ operator

	// cat=24
	case 24:
		op = (int)Rand(9);
		switch (op)
		{
		case 0: // this = num1 ^ num2
			RandBits(&a, TESTBITS);
			RandBits(&b, TESTBITS);
			x2 = REFXOR(A_REFINT, B_REFINT);
			x1 = a ^ b;
			break;

		case 1: // this = this ^ num2
			RandBits(&a, TESTBITS);
			x2 = REFXOR(x2, A_REFINT);
			x1 = x1 ^ a;
			break;

		case 2: // this = num1 ^ this
			RandBits(&a, TESTBITS);
			x2 = REFXOR(A_REFINT, x2);
			x1 = a ^ x1;
			break;

		case 3: // this = num1 ^ 0:num2
			RandBits(&a, TESTBITS);
			RandBits(&b, BASEBITS);
			x2 = REFXOR(A_REFINT, B_BASEINT);
			x1 = a ^ *(BASEINT*)&b;
			break;

		case 4: // this = 0:num1 ^ num2
			RandBits(&a, BASEBITS);
			RandBits(&b, TESTBITS);
			x2 = REFXOR(A_BASEINT, B_REFINT);
			x1 = *(BASEINT*)&a ^ b;
			break;

		case 5: // this = this ^ 0:num2
			RandBits(&b, BASEBITS);
			x2 = REFXOR(x2, B_BASEINT);
			x1 = x1 ^ *(BASEINT*)&b;
			break;

		case 6: // this = 0:num1 ^ this
			RandBits(&a, BASEBITS);
			x2 = REFXOR(A_BASEINT, x2);
			x1 = *(BASEINT*)&a ^ x1;
			break;

		case 7: // this = num1 ^ int
			RandBits(&a, TESTBITS);
			b = (BASEINT)123;
			x2 = REFXOR(A_REFINT, B_REFINT);
			x1 = a ^ (BASEINT)123;
			break;

		case 8: // this = int ^ num2
			a = (BASEINT)123;
			RandBits(&b, TESTBITS);
			x2 = REFXOR(A_REFINT, B_REFINT);
			x1 = (BASEINT)123 ^ b;
			break;

		case 9: // this = this ^ this
			RandBits(&a, TESTBITS);
			x2 = A_REFINT;
			x1 = a;
			x2 = REFXOR(x2, x2);
			x1 = x1 ^ x1;
			break;
		}
		break;

// --- shift operators

	// cat=25
	case 25:
		op = (int)Rand(3);
		switch (op)
		{
		case 0: // this = num << shift
			RandBits(&a, TESTBITS);
			shift = (int)Rand(TESTBITS-1);
			x2 = REFSHL(A_REFINT, shift);
			x1 = a << shift;
			b = (BASEINT)shift;
			break;

		case 1: // this = num << int
			RandBits(&a, TESTBITS);
			x2 = REFSHL(A_REFINT, 12);
			x1 = a << 12;
			break;

		case 2: // this = num >> shift
			RandBits(&a, TESTBITS);
			shift = (int)Rand(TESTBITS-1);
			x2 = REFSHR(A_REFINT, shift);
			x1 = a >> shift;
			b = (BASEINT)shift;
			break;

		case 3: // this = num >> int
			RandBits(&a, TESTBITS);
			x2 = REFSHR(A_REFINT, 12);
			x1 = a >> 12;
			break;
		}
		break;

#ifdef FIXED

#define EPS (TESTBITS/3)

// --- decimal functions

	// cat=26
	case 26:
		op = (int)Rand(10);
		switch (op)
		{
		case 0: // Euler's constant https://www.math.utah.edu/~pa/math/e.html
			{
				const char* t = "2.71828182845904523536028747135266249775724709369995957496696762772407663035354759";
				a.FromText(t);
				x2 = A_REFINT;
				x1 = TESTINT::Eul;
				if (x1.EquEps(a, EPS)) x1 = a;
			}
			break;

		case 1: // Pi constant https://www.math.utah.edu/~pa/math/pi.html
			{
				const char* t = "3.14159265358979323846264338327950288419716939937510582097494459230781640628620899";
				a.FromText(t);
				x2 = A_REFINT;
				x1 = TESTINT::Pi;
				if (x1.EquEps(a, EPS)) x1 = a;
			}
			break;

		case 2: // square root
			{
				RandBits(&a, TESTBITS);
				a.Abs();
				double d = a.Double();
				d = sqrt(d);
				x2 = (REFINT)(d * REFX + 0.5);
				x1.Set(a);
				x1.Sqrt();
				if (x1.EquEps(*(TESTINT*)&x2, EPS)) *(REFINT*)&x1 = x2;
			}
			break;

		case 3: // sin
			{
				RandBits(&a, TESTBITS);
				a.NormRad();
				double d = a.Double();
				d = sin(d);
				x2 = (REFINT)(d * REFX + 0.5);
				x1.Set(a);
				x1.Sin();
				if (x1.EquEps(*(TESTINT*)&x2, EPS)) *(REFINT*)&x1 = x2;
			}
			break;

		case 4: // cos
			{
				RandBits(&a, TESTBITS);
				a.NormRad();
				double d = a.Double();
				d = cos(d);
				x2 = (REFINT)(d * REFX + 0.5);
				x1.Set(a);
				x1.Cos();
				if (x1.EquEps(*(TESTINT*)&x2, EPS)) *(REFINT*)&x1 = x2;
			}
			break;

		case 5: // tan
			{
				RandBits(&a, TESTBITS);
				a.NormRad();
				double d = a.Double();
				if (d > 1.1) d = 1.1; // PI/2 is too much inaccurate
				if (d < -1.1) d = -1.1;
				a.Set(d);
				d = tan(d);
				x2 = (REFINT)(d * REFX + 0.5);
				x1.Set(a);
				x1.Tan();
				if (x1.EquEps(*(TESTINT*)&x2, 2*EPS)) *(REFINT*)&x1 = x2;
			}
			break;

		case 6: // asin
			{
				RandBits(&a, TESTBITS);
				a.NormRad();
				double d = sin(a.Double());
				if ((d > 0.9) && (d < 1.1)) d = 0.9;
				if ((d < -0.9) && (d > -1.1)) d = -0.9;
				a.Set(d);
				d = asin(d);
				x2 = (REFINT)(d * REFX + 0.5);
				x1.Set(a);
				x1.ASin();
				if (x1.EquEps(*(TESTINT*)&x2, EPS)) *(REFINT*)&x1 = x2;
			}
			break;

		case 7: // acos
			{
				RandBits(&a, TESTBITS);
				a.NormRad();
				double d = cos(a.Double());
				if ((d > 0.9) && (d < 1.1)) d = 0.9;
				if ((d < -0.9) && (d > -1.1)) d = -0.9;
				a.Set(d);
				d = acos(d);
				x2 = (REFINT)(d * REFX + 0.5);
				x1.Set(a);
				x1.ACos();
				if (x1.EquEps(*(TESTINT*)&x2, 2*EPS)) *(REFINT*)&x1 = x2;
			}
			break;

		case 8: // atan
			{
				RandBits(&a, TESTBITS);
				a.NormRad();
				double d = a.Double();
				if (d > 0.7) d = 0.7; // too much inaccurate
				if (d < -0.7) d = -0.7;
				d = tan(d);
				a.Set(d);
				d = atan(d);
				x2 = (REFINT)(d * REFX + 0.5);
				x1.Set(a);
				x1.ATan();
				if (x1.EquEps(*(TESTINT*)&x2, 2*EPS)) *(REFINT*)&x1 = x2;
			}
			break;

		case 9: // log
			{
				RandBits(&a, TESTBITS);
				a.Abs();
				double d = a.Double();
				d = log(d);
				x2 = (REFINT)(d * REFX + 0.5);
				x1.Set(a);
				x1.Log();
				if (x1.EquEps(*(TESTINT*)&x2, EPS)) *(REFINT*)&x1 = x2;
			}
			break;

		case 10: // exp
			{
				RandBits(&a, TESTBITS);
				a.Abs();
				double d = a.Double();
				if (d < 0.1) d = 0.1;
				if (d > 10) d = 10;
				d = log(d);
				a.Set(d);
				d = exp(d);
				x2 = (REFINT)(d * REFX + 0.5);
				x1.Set(a);
				x1.Exp();
				if (x1.EquEps(*(TESTINT*)&x2, 5*EPS)) *(REFINT*)&x1 = x2;
			}
			break;
		}
		break;
#endif // FIXED
	}
}

// clear output
printf("\r%s ... OK                  \r\n", name);

#undef TESTINT		// tested number class
#undef REFINT		// reference number class
#undef REFISCLS		// 1=reference number is class, 0=reference number is integer
#undef BASEINT		// base integer
#undef HALFINT		// half integer
#undef TESTBITS		// number of bits

#undef SIGNED		// flag - signed number

#undef FIXED		// flag - fix point number

#undef DBLINT1		// double integer class for tested number
#undef DBLINT2		// double integer for reference number

#undef BASEBITS		// number of bits of base number
#undef HALFBITS		// number of bits of half number

#undef REFS			// shifts of integer of referencenumber
#undef REFX			// multiplier of reference number

#undef A_REFINT		// get reference number from a
#undef B_REFINT		// get reference number from b
#undef A_BASEINT	// get reference base number from a
#undef B_BASEINT	// get reference base number from b
#undef A_HALFINT	// get reference half number from a
#undef B_HALFINT	// get reference half number from b
#undef A_DBLINT		// get reference dblint number from a
#undef B_DBLINT		// get reference dblint number from b

#undef REFADD		// ADD reference number
#undef REFSUB		// SUB reference number
#undef REFINC		// INC reference number
#undef REFDEC		// DEC reference number
#undef REFMUL		// MUL reference number
#undef REFDIV		// DIV reference number
#undef REFMOD		// MOD reference number

#undef REFCMP		// compare reference number

#undef REFNOT		// NOT reference number
#undef REFAND		// AND reference number
#undef REFOR		// OR reference number
#undef REFXOR		// XOR reference number
#undef REFSHL		// shift left reference number
#undef REFSHR		// shift right reference number

#undef DBLBITS		// number of bits of double number
