From e1ca6741238688b26b7d044921a0fb08b025c5dc Mon Sep 17 00:00:00 2001 From: Alexey Sheplyakov Date: Wed, 1 Jan 2020 12:22:31 +0100 Subject: [PATCH] Fixed factorial calculation on 64-bit windows. --- .../misc/combin/cl_I_doublefactorial.cc | 66 +++++++++---------- src/integer/misc/combin/cl_I_factorial.cc | 40 +++++------ tests/Makefile.am | 1 + tests/test_I.cc | 4 ++ tests/test_I_factorial.cc | 15 +++++ 5 files changed, 73 insertions(+), 53 deletions(-) create mode 100644 tests/test_I_factorial.cc diff --git a/src/integer/misc/combin/cl_I_doublefactorial.cc b/src/integer/misc/combin/cl_I_doublefactorial.cc index 74acc91..b811632 100644 --- a/src/integer/misc/combin/cl_I_doublefactorial.cc +++ b/src/integer/misc/combin/cl_I_doublefactorial.cc @@ -30,68 +30,68 @@ const cl_I doublefactorial (uintL n) // assume n >= 0 small { static cl_I const doublefakul_table [] = { 1, - 1UL, - 1UL*2, - 1UL*3, + UINT64_C(1), + UINT64_C(1)*2, + UINT64_C(1)*3, #if (cl_value_len>=5) - 1UL*2*4, - 1UL*3*5, + UINT64_C(1)*2*4, + UINT64_C(1)*3*5, #if (cl_value_len>=7) - 1UL*2*4*6, + UINT64_C(1)*2*4*6, #if (cl_value_len>=8) - 1UL*3*5*7, + UINT64_C(1)*3*5*7, #if (cl_value_len>=10) - 1UL*2*4*6*8, + UINT64_C(1)*2*4*6*8, #if (cl_value_len>=11) - 1UL*3*5*7*9, + UINT64_C(1)*3*5*7*9, #if (cl_value_len>=13) - 1UL*2*4*6*8*10, + UINT64_C(1)*2*4*6*8*10, #if (cl_value_len>=15) - 1UL*3*5*7*9*11, + UINT64_C(1)*3*5*7*9*11, #if (cl_value_len>=17) - 1UL*2*4*6*8*10*12, + UINT64_C(1)*2*4*6*8*10*12, #if (cl_value_len>=19) - 1UL*3*5*7*9*11*13, + UINT64_C(1)*3*5*7*9*11*13, #if (cl_value_len>=21) - 1UL*2*4*6*8*10*12*14, + UINT64_C(1)*2*4*6*8*10*12*14, #if (cl_value_len>=22) - 1UL*3*5*7*9*11*13*15, + UINT64_C(1)*3*5*7*9*11*13*15, #if (cl_value_len>=25) - 1UL*2*4*6*8*10*12*14*16, + UINT64_C(1)*2*4*6*8*10*12*14*16, #if (cl_value_len>=27) - 1UL*3*5*7*9*11*13*15*17, + UINT64_C(1)*3*5*7*9*11*13*15*17, #if (cl_value_len>=29) - 1UL*2*4*6*8*10*12*14*16*18, + UINT64_C(1)*2*4*6*8*10*12*14*16*18, #if (cl_value_len>=31) - 1UL*3*5*7*9*11*13*15*17*19, + UINT64_C(1)*3*5*7*9*11*13*15*17*19, #if (cl_value_len>=33) - 1UL*2*4*6*8*10*12*14*16*18*20, + UINT64_C(1)*2*4*6*8*10*12*14*16*18*20, #if (cl_value_len>=35) - 1UL*3*5*7*9*11*13*15*17*19*21, + UINT64_C(1)*3*5*7*9*11*13*15*17*19*21, #if (cl_value_len>=38) - 1UL*2*4*6*8*10*12*14*16*18*20*22, + UINT64_C(1)*2*4*6*8*10*12*14*16*18*20*22, #if (cl_value_len>=40) - 1UL*3*5*7*9*11*13*15*17*19*21*23, + UINT64_C(1)*3*5*7*9*11*13*15*17*19*21*23, #if (cl_value_len>=42) - 1UL*2*4*6*8*10*12*14*16*18*20*22*24, + UINT64_C(1)*2*4*6*8*10*12*14*16*18*20*22*24, #if (cl_value_len>=44) - 1UL*3*5*7*9*11*13*15*17*19*21*23*25, + UINT64_C(1)*3*5*7*9*11*13*15*17*19*21*23*25, #if (cl_value_len>=47) - 1UL*2*4*6*8*10*12*14*16*18*20*22*24*26, + UINT64_C(1)*2*4*6*8*10*12*14*16*18*20*22*24*26, #if (cl_value_len>=49) - 1UL*3*5*7*9*11*13*15*17*19*21*23*25*27, + UINT64_C(1)*3*5*7*9*11*13*15*17*19*21*23*25*27, #if (cl_value_len>=52) - 1UL*2*4*6*8*10*12*14*16*18*20*22*24*26*28, + UINT64_C(1)*2*4*6*8*10*12*14*16*18*20*22*24*26*28, #if (cl_value_len>=54) - 1UL*3*5*7*9*11*13*15*17*19*21*23*25*27*29, + UINT64_C(1)*3*5*7*9*11*13*15*17*19*21*23*25*27*29, #if (cl_value_len>=57) - 1UL*2*4*6*8*10*12*14*16*18*20*22*24*26*28*30, + UINT64_C(1)*2*4*6*8*10*12*14*16*18*20*22*24*26*28*30, #if (cl_value_len>=59) - 1UL*3*5*7*9*11*13*15*17*19*21*23*25*27*29*31, + UINT64_C(1)*3*5*7*9*11*13*15*17*19*21*23*25*27*29*31, #if (cl_value_len>=62) - 1UL*2*4*6*8*10*12*14*16*18*20*22*24*26*28*30*32, + UINT64_C(1)*2*4*6*8*10*12*14*16*18*20*22*24*26*28*30*32, #if (cl_value_len>=64) - 1UL*3*5*7*9*11*13*15*17*19*21*23*25*27*29*31*33, + UINT64_C(1)*3*5*7*9*11*13*15*17*19*21*23*25*27*29*31*33, #if (cl_value_len>=67) ... #endif diff --git a/src/integer/misc/combin/cl_I_factorial.cc b/src/integer/misc/combin/cl_I_factorial.cc index 98b9052..7a8235f 100644 --- a/src/integer/misc/combin/cl_I_factorial.cc +++ b/src/integer/misc/combin/cl_I_factorial.cc @@ -32,44 +32,44 @@ const cl_I factorial (uintL n) // assume n >= 0 small { static uintV const fakul_table [] = { 1, - 1UL, - 1UL*2, + UINT64_C(1), + UINT64_C(1)*2, #if (cl_value_len>=4) - 1UL*2*3, + UINT64_C(1)*2*3, #if (cl_value_len>=6) - 1UL*2*3*4, + UINT64_C(1)*2*3*4, #if (cl_value_len>=8) - 1UL*2*3*4*5, + UINT64_C(1)*2*3*4*5, #if (cl_value_len>=11) - 1UL*2*3*4*5*6, + UINT64_C(1)*2*3*4*5*6, #if (cl_value_len>=14) - 1UL*2*3*4*5*6*7, + UINT64_C(1)*2*3*4*5*6*7, #if (cl_value_len>=17) - 1UL*2*3*4*5*6*7*8, + UINT64_C(1)*2*3*4*5*6*7*8, #if (cl_value_len>=20) - 1UL*2*3*4*5*6*7*8*9, + UINT64_C(1)*2*3*4*5*6*7*8*9, #if (cl_value_len>=23) - 1UL*2*3*4*5*6*7*8*9*10, + UINT64_C(1)*2*3*4*5*6*7*8*9*10, #if (cl_value_len>=27) - 1UL*2*3*4*5*6*7*8*9*10*11, + UINT64_C(1)*2*3*4*5*6*7*8*9*10*11, #if (cl_value_len>=30) - 1UL*2*3*4*5*6*7*8*9*10*11*12, + UINT64_C(1)*2*3*4*5*6*7*8*9*10*11*12, #if (cl_value_len>=34) - 1UL*2*3*4*5*6*7*8*9*10*11*12*13, + UINT64_C(1)*2*3*4*5*6*7*8*9*10*11*12*13, #if (cl_value_len>=38) - 1UL*2*3*4*5*6*7*8*9*10*11*12*13*14, + UINT64_C(1)*2*3*4*5*6*7*8*9*10*11*12*13*14, #if (cl_value_len>=42) - 1UL*2*3*4*5*6*7*8*9*10*11*12*13*14*15, + UINT64_C(1)*2*3*4*5*6*7*8*9*10*11*12*13*14*15, #if (cl_value_len>=46) - 1UL*2*3*4*5*6*7*8*9*10*11*12*13*14*15*16, + UINT64_C(1)*2*3*4*5*6*7*8*9*10*11*12*13*14*15*16, #if (cl_value_len>=50) - 1UL*2*3*4*5*6*7*8*9*10*11*12*13*14*15*16*17, + UINT64_C(1)*2*3*4*5*6*7*8*9*10*11*12*13*14*15*16*17, #if (cl_value_len>=54) - 1UL*2*3*4*5*6*7*8*9*10*11*12*13*14*15*16*17*18, + UINT64_C(1)*2*3*4*5*6*7*8*9*10*11*12*13*14*15*16*17*18, #if (cl_value_len>=58) - 1UL*2*3*4*5*6*7*8*9*10*11*12*13*14*15*16*17*18*19, + UINT64_C(1)*2*3*4*5*6*7*8*9*10*11*12*13*14*15*16*17*18*19, #if (cl_value_len>=63) - 1UL*2*3*4*5*6*7*8*9*10*11*12*13*14*15*16*17*18*19*20, + UINT64_C(1)*2*3*4*5*6*7*8*9*10*11*12*13*14*15*16*17*18*19*20, #if (cl_value_len>=67) ... #endif diff --git a/tests/Makefile.am b/tests/Makefile.am index 7dfe406..57c0777 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -78,6 +78,7 @@ tests_SOURCES = test.h tests.cc test_I.cc test_I.h test_I_abs.cc test_I_compare. test_I_logcount.cc test_I_ilength.cc test_I_ord2.cc \ test_I_power2p.cc test_I_isqrt.cc test_I_sqrtp.cc \ test_I_io.cc test_I_GV.cc \ + test_I_factorial.cc \ test_MI.h test_MI.cc test_MI_canonhom.cc test_MI_plus.cc \ test_MI_minus.cc test_MI_mul.cc test_MI_recip.cc \ test_MI_div.cc test_MI_expt.cc \ diff --git a/tests/test_I.cc b/tests/test_I.cc index 8e5ea63..5338a31 100644 --- a/tests/test_I.cc +++ b/tests/test_I.cc @@ -45,6 +45,8 @@ extern int test_I_sqrtp (int iterations); // Miscellaneous. extern int test_I_io (int iterations); extern int test_I_GV (int iterations); +extern int test_I_factorial(int iterations); +extern int test_I_doublefactorial(int iterations); #define RUN(tester,iterations) \ std::cout << "Testing "#tester"..." << std::endl; \ @@ -99,5 +101,7 @@ int test_I (int iterations) // Miscellaneous. RUN(test_I_io,iterations); RUN(test_I_GV,iterations); + RUN(test_I_factorial, iterations); + RUN(test_I_doublefactorial, iterations); return error; } diff --git a/tests/test_I_factorial.cc b/tests/test_I_factorial.cc new file mode 100644 index 0000000..bae2513 --- /dev/null +++ b/tests/test_I_factorial.cc @@ -0,0 +1,15 @@ +#include "test_I.h" + +int test_I_factorial(int /* iterations */) { + int error = 0; + cl_I result = factorial(14U); + ASSERT1(result > cl_I(UINT64_C(1) << 32), result); + return error; +} + +int test_I_doublefactorial(int /* iterations */) { + int error = 0; + cl_I result = doublefactorial(21U); + ASSERT1(result > cl_I(UINT64_C(1) << 32), result); + return error; +} -- 2.49.0