You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
112 lines
2.9 KiB
112 lines
2.9 KiB
#include <cln/integer.h>
|
|
#include <cln/integer_io.h>
|
|
#include <cln/io.h>
|
|
|
|
using namespace std;
|
|
using namespace cln;
|
|
|
|
#define ASSERT(expr) \
|
|
if (!(expr)) { \
|
|
std::cerr << "Assertion failed! File " << __FILE__ << ", line " << __LINE__ << endl; \
|
|
error = 1; \
|
|
}
|
|
|
|
struct gcd_test {
|
|
const char * arg1;
|
|
const char * arg2;
|
|
const char * result;
|
|
};
|
|
|
|
#define num_elements(array) (sizeof(array)/sizeof(array[0]))
|
|
|
|
// Note: This macro differs slightly from the one in "exam.h".
|
|
#define DO_BINOP_TEST(typename,type,rtype,opname) \
|
|
static int test_##typename##_##opname (void) \
|
|
{ \
|
|
int error = 0; \
|
|
for (unsigned int i = 0; i < num_elements(typename##_##opname##_tests); i++) { \
|
|
opname##_test& test = typename##_##opname##_tests[i]; \
|
|
type arg1 = type(test.arg1); \
|
|
type arg2 = type(test.arg2); \
|
|
rtype computed_result = opname(arg1,arg2); \
|
|
rtype result = rtype(test.result); \
|
|
if (computed_result != result) { \
|
|
std::cerr << "Error in " #typename "_" #opname "_tests[" << i << "] !" << endl; \
|
|
std::cerr << "Result should be: " << result << endl; \
|
|
std::cerr << "Result computed : " << computed_result << endl << endl; \
|
|
error = 1; \
|
|
} \
|
|
} \
|
|
return error; \
|
|
}
|
|
|
|
static gcd_test integer_gcd_tests[] = {
|
|
{ "123456789", "345", "3" },
|
|
{ "345", "123456789", "3" },
|
|
{ "10", "0", "10" },
|
|
{ "0", "10", "10" },
|
|
{ "2523533737", "855322739", "1" },
|
|
{ "855322739", "2523533737", "1" },
|
|
{ "101611479673163974026724715741235467160607959655653420075620", "533177863832047932237026621580126811198495699416238676294977", "1" },
|
|
{ "30729415811", "323233683197", "31071199" },
|
|
{ "77874422", "32223899", "1" },
|
|
{ "974507656412513757857315037382926980395082974811562770185617915360", "-1539496810360685510909469177732386446833404488164283", "1" },
|
|
{ "2823618260546496405819033080103700734250203999069672146446", "18374686479688400895", "1" }
|
|
};
|
|
|
|
DO_BINOP_TEST(integer,cl_I,cl_I,gcd)
|
|
|
|
int test_gcd (void)
|
|
{
|
|
int error = 0;
|
|
error |= test_integer_gcd();
|
|
return error;
|
|
}
|
|
|
|
int test_xgcd (void)
|
|
{
|
|
int error = 0;
|
|
{
|
|
cl_I a = 77874422;
|
|
cl_I b = 32223899;
|
|
cl_I u;
|
|
cl_I v;
|
|
cl_I g = xgcd(a,b, &u,&v);
|
|
ASSERT(g == 1);
|
|
ASSERT(g == a*u+b*v);
|
|
ASSERT(u == -9206830);
|
|
ASSERT(v == 22249839);
|
|
}
|
|
{
|
|
cl_I a = "560014183";
|
|
cl_I b = 312839871;
|
|
cl_I u;
|
|
cl_I v;
|
|
cl_I g = xgcd(a,b, &u,&v);
|
|
ASSERT(g == 1);
|
|
ASSERT(g == a*u+b*v);
|
|
ASSERT(u == 77165803);
|
|
ASSERT(v == -138134388);
|
|
}
|
|
{
|
|
cl_I a = "#x80000000";
|
|
cl_I b = "#x-C0000000";
|
|
cl_I u;
|
|
cl_I v;
|
|
cl_I g = xgcd(a,b, &u,&v);
|
|
ASSERT(g == (cl_I)"#x40000000");
|
|
ASSERT(g == a*u+b*v);
|
|
ASSERT(u == -1);
|
|
ASSERT(v == -1);
|
|
}
|
|
{
|
|
cl_I a = "974507656412513757857315037382926980395082974811562770185617915360";
|
|
cl_I b = "-1539496810360685510909469177732386446833404488164283";
|
|
cl_I u;
|
|
cl_I v;
|
|
cl_I g = xgcd(a,b, &u,&v);
|
|
ASSERT(g == 1);
|
|
ASSERT(g == a*u+b*v);
|
|
}
|
|
return error;
|
|
}
|