1 #pragma once
2 //  test_case.cpp : functions to generate specific test cases
3 //
4 // Copyright (C) 2017-2021 Stillwater Supercomputing, Inc.
5 //
6 // This file is part of the universal numbers project, which is released under an MIT Open Source license.
7 #include <iostream>
8 #include <iomanip>
9 
10 namespace sw::universal {
11 
12 	enum class TestCaseOperator { ADD, SUB, MUL, DIV };  // basic arithmetic operators supported by all number systems
13 
14 	// generate an arithmetic test case
15 	template<typename Number, typename Ty>
TestCase(TestCaseOperator _operator,Ty _a,Ty _b)16 	void TestCase(TestCaseOperator _operator, Ty _a, Ty _b) {
17 		constexpr size_t nbits = Number::nbits;
18 		Number c(0);
19 		Ty _c(0);
20 		std::string op, opName;
21 		Number a = _a;
22 		Number b = _b;
23 		switch (_operator) {
24 		case TestCaseOperator::ADD:
25 			c = a + b;
26 			_c = _a + _b;
27 			op     = " + ";
28 			opName = "ADD";
29 			break;
30 		case TestCaseOperator::SUB:
31 			c = a - b;
32 			_c = _a - _b;
33 			op = " - ";
34 			opName = "SUB";
35 			break;
36 		case TestCaseOperator::MUL:
37 			c = a * b;
38 			_c = _a * _b;
39 			op = " * ";
40 			opName = "MUL";
41 			break;
42 		case TestCaseOperator::DIV:
43 			c = a / b;
44 			_c = _a / _b;
45 			op = " / ";
46 			opName = "DIV";
47 			break;
48 		default:
49 			std::cout << "Unknown operator: exiting\n";
50 			return;
51 		}
52 		// sample the reference into the target Number to be the golden value
53 		Number reference = _c;
54 
55 		auto oldprecision = std::cout.precision();
56 		std::cout << std::setprecision(10);
57 		std::cout << "+--------  Test Case: " << opName << "\ninput operands : " << typeid(Ty).name() << '\n';
58 		std::cout << std::setw(nbits) << _a << op << std::setw(nbits) << _b << " = " << std::setw(nbits) << _c << std::endl;
59 		std::cout << to_binary(_a) << " : " << _a << '\n';
60 		std::cout << to_binary(_b) << " : " << _b << '\n';
61 		std::cout << to_binary(_c) << " : " << _c << '\n';
62 		std::cout << "+--------\ntarget number : " << typeid(Number).name() << '\n';
63 		std::cout << a << op << b << " = " << c << " (reference: " << reference << ")\n";
64 		std::cout << to_binary(a, true) << op << to_binary(b, true) << " = " << to_binary(c, true) << " (reference: " << to_binary(reference, true) << ")   ";
65 		std::cout << (reference == c ? "PASS" : "FAIL");
66 		std::cout << "\n+--------  Test Case: Done\n";
67 		std::cout << std::setprecision(oldprecision);
68 	}
69 
70 } // namespace sw::universal
71