Files
Upsilon/poincare/test/integer.cpp
Gabriel Ozouf 6e9a5a010f [poincare/integer] Add tests on euclidean division
This commit also adds tests on mixed fractions.

Change-Id: I0fee88eb00febccaa9445230f8f2bbb92cd1ba98
2020-11-04 15:32:59 +01:00

306 lines
16 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "helper.h"
using namespace Poincare;
static inline Integer MaxInteger() { return Integer(MaxIntegerString()); }
static inline Integer OverflowedInteger() { return Integer(OverflowedIntegerString()); }
QUIZ_CASE(poincare_integer_constructor) {
Integer zero;
Integer a("123");
Integer na("-123");
Integer b("12345678910111213141516");
Integer nb("-12345678910111213141516");
Integer c(12314);
Integer nc(-12314);
Integer d((int64_t)1234567891011121314);
Integer nd((int64_t)(-1234567891011121314));
Integer e = Integer::Overflow(false);
Integer f("101011", 6, false, Integer::Base::Binary);
Integer g("A2B3", 4, false, Integer::Base::Hexadecimal);
Integer h("123", 3, false, Integer::Base::Decimal);
}
static inline void assert_equal(const Integer i, const Integer j) {
quiz_assert(Integer::NaturalOrder(i, j) == 0);
}
static inline void assert_not_equal(const Integer i, const Integer j) {
quiz_assert(Integer::NaturalOrder(i, j) != 0);
}
static inline void assert_lower(const Integer i, const Integer j) {
quiz_assert(Integer::NaturalOrder(i, j) < 0);
}
static inline void assert_greater(const Integer i, const Integer j) {
quiz_assert(Integer::NaturalOrder(i, j) > 0);
}
QUIZ_CASE(poincare_integer_compare) {
assert_equal(Integer(123), Integer(123));
assert_equal(Integer(-123), Integer(-123));
assert_equal(Integer("123"), Integer(123));
assert_not_equal(Integer("-123"), Integer(123));
assert_equal(Integer("-123"), Integer(-123));
assert_equal(Integer((int64_t)1234567891011121314), Integer((int64_t)1234567891011121314));
assert_equal(Integer("1234567891011121314"), Integer((int64_t)1234567891011121314));
assert_not_equal(Integer("-1234567891011121314"), Integer((int64_t)1234567891011121314));
assert_lower(Integer(123), Integer(456));
assert_greater(Integer(456), Integer(123));
assert_lower(Integer(-100), Integer(2));
assert_lower(Integer(-200), Integer(-100));
assert_lower(Integer(123), Integer("123456789123456789"));
assert_lower(Integer(-123), Integer("123456789123456789"));
assert_lower(Integer("123456789123456788"), Integer("123456789123456789"));
assert_lower(Integer("-1234567891234567892109209109"), Integer("123456789123456789"));
assert_greater(Integer("123456789123456789"), Integer("123456789123456788"));
assert_greater(Integer::Overflow(false), Integer("123456789123456788"));
//FIXME: quiz_assert(Integer("0x2BABE") == Integer(178878));
//FIXME: quiz_assert(Integer("0b1011") == Integer(11));
}
QUIZ_CASE(poincare_integer_properties) {
quiz_assert(Integer(0).isZero());
quiz_assert(!Integer(-1).isZero());
quiz_assert(!Integer(1).isZero());
quiz_assert(Integer(1).isOne());
quiz_assert(!Integer(-1).isOne());
quiz_assert(!Integer(0).isOne());
quiz_assert(OverflowedInteger().isOverflow()); // 2^32^k_maxNumberOfDigits
quiz_assert(!MaxInteger().isOverflow()); // 2^32^k_maxNumberOfDigits-1
quiz_assert(!Integer(0).isOverflow());
quiz_assert(Integer(8).isEven());
quiz_assert(!Integer(7).isEven());
quiz_assert(Integer(-8).isEven());
quiz_assert(!Integer(-7).isEven());
quiz_assert(!Integer(2).isNegative());
quiz_assert(Integer(-2).isNegative());
quiz_assert(Integer::NumberOfBase10DigitsWithoutSign(MaxInteger()) == 309);
}
static inline void assert_add_to(const Integer i, const Integer j, const Integer k) {
quiz_assert(Integer::NaturalOrder(Integer::Addition(i, j), k) == 0);
}
QUIZ_CASE(poincare_integer_addition) {
assert_add_to(Integer("0"), Integer("0"), Integer(0));
assert_add_to(Integer(123), Integer(456), Integer(579));
assert_add_to(Integer(123), Integer(456), Integer(579));
assert_add_to(Integer("123456789123456789"), Integer(1), Integer("123456789123456790"));
assert_add_to(Integer("-123456789123456789"), Integer("123456789123456789"), Integer("0"));
assert_add_to(Integer("234"), Integer(-234), Integer(0));
assert_add_to(Integer("18446744073709551616"), Integer("18446744073709551368"), Integer("36893488147419102984"));
//2^64+2^64
assert_add_to(Integer("18446744073709551616"), Integer("18446744073709551616"), Integer("36893488147419103232"));
//2^64+2^32
assert_add_to(Integer("18446744073709551616"), Integer("4294967296"), Integer("18446744078004518912"));
//2^64+1
assert_add_to(Integer("18446744073709551616"), Integer("1"), Integer("18446744073709551617"));
//2^32+2^32
assert_add_to(Integer("4294967296"), Integer("4294967296"), Integer("8589934592"));
//2^32+1
assert_add_to(Integer("4294967296"), Integer("1"), Integer("4294967297"));
//2^16+1
assert_add_to(Integer("65537"), Integer("1"), Integer("65538"));
//2^16+2^16
assert_add_to(Integer("65537"), Integer("65537"), Integer("131074"));
}
static inline void assert_sub_to(const Integer i, const Integer j, const Integer k) {
quiz_assert(Integer::NaturalOrder(Integer::Subtraction(i, j), k) == 0);
}
QUIZ_CASE(poincare_integer_subtraction) {
assert_sub_to(Integer(123), Integer(23), Integer(100));
assert_sub_to(Integer("123456789123456789"), Integer("9999999999"), Integer("123456779123456790"));
assert_sub_to(Integer(23), Integer(100), Integer(-77));
assert_sub_to(Integer(23), Integer(23), Integer(0));
assert_sub_to(Integer(-23), Integer(-23), Integer(0));
assert_sub_to(Integer("-123456789123456789"), Integer("-123456789123456789"), Integer(0));
assert_sub_to(Integer("123456789123456789"), Integer("123456789123456789"), Integer(0));
assert_sub_to(Integer("18446744073709551616"), Integer("18446744073709551368"), Integer(248));
//2^64-2^64
assert_sub_to(Integer("18446744073709551616"), Integer("18446744073709551616"), Integer("0"));
//2^64-2^32
assert_sub_to(Integer("18446744073709551616"), Integer("4294967296"), Integer("18446744069414584320"));
//2^32-2^64
assert_sub_to(Integer("4294967296"), Integer("18446744073709551616"), Integer("-18446744069414584320"));
//2^64-1
assert_sub_to(Integer("18446744073709551616"), Integer("1"), Integer("18446744073709551615"));
//1-2^64
assert_sub_to(Integer("1"), Integer("18446744073709551616"), Integer("-18446744073709551615"));
//2^32-2^32
assert_sub_to(Integer("4294967296"), Integer("4294967296"), Integer("0"));
//2^32-1
assert_sub_to(Integer("4294967296"), Integer("1"), Integer("4294967295"));
//2^16-1
assert_sub_to(Integer("65537"), Integer("1"), Integer("65536"));
//2^16-2^16
assert_sub_to(Integer("65537"), Integer("65537"), Integer("0"));
}
static inline void assert_mult_to(const Integer i, const Integer j, const Integer k) {
quiz_assert(Integer::NaturalOrder(Integer::Multiplication(i, j), k) == 0);
}
QUIZ_CASE(poincare_integer_multiplication) {
assert_mult_to(Integer(12), Integer(34), Integer(408));
assert_mult_to(Integer(56), Integer(0), Integer(0));
assert_mult_to(Integer(-12), Integer(34), Integer(-408));
assert_mult_to(Integer(-12), Integer(-34), Integer(408));
assert_mult_to(Integer(123456), Integer(654321), Integer("80779853376"));
assert_mult_to(Integer("9999999999"), Integer("9999999999"), Integer("99999999980000000001"));
assert_mult_to(Integer("-23"), Integer("0"), Integer("0"));
assert_mult_to(Integer("-23456787654567765456"), Integer("0"), Integer("0"));
assert_mult_to(Integer("3293920983030066"), Integer(720), Integer("2371623107781647520"));
assert_mult_to(Integer("389282362616"), Integer(720), Integer("280283301083520"));
}
static inline void assert_div_to(const Integer i, const Integer j, const Integer q, const Integer r) {
quiz_assert(Integer::NaturalOrder(Integer::Division(i, j).quotient, q) == 0);
quiz_assert(Integer::NaturalOrder(Integer::Division(i, j).remainder, r) == 0);
}
QUIZ_CASE(poincare_integer_divide) {
assert_div_to(Integer("146097313984800"), Integer(720), Integer("202912936090"), Integer(0));
assert_div_to(Integer(8), Integer(4), Integer(2), Integer(0));
assert_div_to(Integer("3293920983030066"), Integer(38928), Integer("84615726033"), Integer(17442));
assert_div_to(Integer("3293920983030066"), Integer("389282362616"), Integer(8461), Integer("202912936090"));
assert_div_to(Integer("-18940566"), Integer("499030"), Integer(-38), Integer("22574"));
assert_div_to(Integer("234567909876"), Integer("-234567898"), Integer(-1000), Integer("11876"));
assert_div_to(Integer("-567"), Integer("-12"), Integer(48), Integer("9"));
assert_div_to(Integer("-576"), Integer("-12"), Integer(48), Integer("0"));
assert_div_to(Integer("576"), Integer("-12"), Integer(-48), Integer("0"));
assert_div_to(Integer("-576"), Integer("12"), Integer(-48), Integer("0"));
assert_div_to(Integer("12345678910111213141516171819202122232425"), Integer("10"), Integer("1234567891011121314151617181920212223242"), Integer("5"));
assert_div_to(Integer("1234567891011121314151617181920212223242"), Integer("10"), Integer("123456789101112131415161718192021222324"), Integer("2"));
assert_div_to(Integer("123456789101112131415161718192021222324"), Integer("10"), Integer("12345678910111213141516171819202122232"), Integer("4"));
assert_div_to(Integer("12345678910111213141516171819202122232"), Integer("10"), Integer("1234567891011121314151617181920212223"), Integer("2"));
assert_div_to(Integer("1234567891011121314151617181920212223"), Integer("10"), Integer("123456789101112131415161718192021222"), Integer("3"));
assert_div_to(Integer("123456789101112131415161718192021222"), Integer("10"), Integer("12345678910111213141516171819202122"), Integer("2"));
assert_div_to(Integer("12345678910111213141516171819202122"), Integer("10"), Integer("1234567891011121314151617181920212"), Integer("2"));
assert_div_to(Integer("0"), Integer("-10"), Integer("0"), Integer("0"));
assert_div_to(Integer("0"), Integer("-123456789098760"), Integer("0"), Integer("0"));
assert_div_to(Integer("2305843009213693952"), Integer("2305843009213693921"), Integer("1"), Integer("31"));
assert_div_to(MaxInteger(), MaxInteger(), Integer(1), Integer(0));
assert_div_to(Integer("18446744073709551615"), Integer(10), Integer("1844674407370955161"), Integer(5));
assert_div_to(MaxInteger(), Integer(10), Integer("17976931348623159077293051907890247336179769789423065727343008115773267580550096313270847732240753602112011387987139335765878976881441662249284743063947412437776789342486548527630221960124609411945308295208500576883815068234246288147391311054082723716335051068458629823994724593847971630483535632962422413721"), Integer(5));
}
static inline void assert_pow_to(const Integer i, const Integer j, const Integer k) {
quiz_assert(Integer::NaturalOrder(Integer::Power(i, j), k) == 0);
}
QUIZ_CASE(poincare_integer_pow) {
assert_pow_to(Integer(2), Integer(2), Integer(4));
assert_pow_to(Integer("12345678910111213141516171819202122232425"), Integer(2), Integer("152415787751564791571474464067365843004067618915106260955633159458990465721380625"));
}
static inline void assert_factorial_to(const Integer i, const Integer j) {
quiz_assert(Integer::NaturalOrder(Integer::Factorial(i), j) == 0);
}
QUIZ_CASE(poincare_integer_factorial) {
assert_factorial_to(Integer(5), Integer(120));
assert_factorial_to(Integer(123), Integer("12146304367025329675766243241881295855454217088483382315328918161829235892362167668831156960612640202170735835221294047782591091570411651472186029519906261646730733907419814952960000000000000000000000000000"));
}
// Simplify
template<typename T>
void assert_integer_evals_to(const char * i, T result, Integer::Base base = Integer::Base::Decimal) {
quiz_assert(Integer(i, strlen(i), false, base).approximate<T>() == result);
}
QUIZ_CASE(poincare_integer_evaluate) {
assert_integer_evals_to("1", 1.0f);
assert_integer_evals_to("1", 1.0);
assert_integer_evals_to("12345678", 12345678.0f);
assert_integer_evals_to("12345678", 12345678.0);
assert_integer_evals_to("0", 0.0f);
assert_integer_evals_to("0", 0.0);
assert_integer_evals_to("-0", 0.0f);
assert_integer_evals_to("-0", 0.0);
assert_integer_evals_to("-1", -1.0f);
assert_integer_evals_to("-1", -1.0);
assert_integer_evals_to("12345678", 12345678.0f);
assert_integer_evals_to("12345678", 12345678.0);
assert_integer_evals_to("4294967295", 4294967295.0f);
assert_integer_evals_to("4294967295", 4294967295.0);
assert_integer_evals_to("-4294967296", -4294967296.0f);
assert_integer_evals_to("-4294967296", -4294967296.0);
assert_integer_evals_to("2147483648", 2147483648.0f);
assert_integer_evals_to("2147483648", 2147483648.0);
assert_integer_evals_to("-18446744073709551615", -18446744073709551615.0f);
assert_integer_evals_to("-18446744073709551615", -18446744073709551615.0);
assert_integer_evals_to("-18446744073709551616", -18446744073709551616.0f);
assert_integer_evals_to("-18446744073709551616", -18446744073709551616.0);
assert_integer_evals_to("92233720372036854775808", 92233720372036854775808.0f);
assert_integer_evals_to("92233720372036854775808", 92233720372036854775808.0);
assert_integer_evals_to("134217720", 134217720.0f);
assert_integer_evals_to("134217720", 134217720.0);
assert_integer_evals_to("67108864", 67108864.0f);
assert_integer_evals_to("67108864", 67108864.0);
assert_integer_evals_to("33554432", 33554432.0f);
assert_integer_evals_to("33554432", 33554432.0);
assert_integer_evals_to("2", 2.0f);
assert_integer_evals_to("2", 2.0);
assert_integer_evals_to("4", 4.0f);
assert_integer_evals_to("4", 4.0);
assert_integer_evals_to("179769313486230000002930519078902473361797697894230657273430081157732675805500963132708477322407536021120113879871393357658789768814416622492847430639474124377767893424865485276302219601246094119453082952085005768838150682342462881473913110540827237163350510684586298239947245938479716304835356329624224137215", 1.7976931348622999E+308);
assert_integer_evals_to(OverflowedIntegerString(), 179769313486231590772930519078902473361797697894230657273430081157732675805500963132708477322407536021120113879871393357658789768814416622492847430639474124377767893424865485276302219601246094119453082952085005768838150682342462881473913110540827237163350510684586298239947245938479716304835356329624224137216.0);
assert_integer_evals_to(MaxIntegerString(), 179769313486231590772930519078902473361797697894230657273430081157732675805500963132708477322407536021120113879871393357658789768814416622492847430639474124377767893424865485276302219601246094119453082952085005768838150682342462881473913110540827237163350510684586298239947245938479716304835356329624224137215.0);
// Based Integer
assert_integer_evals_to("1011", 11.0f, Integer::Base::Binary);
assert_integer_evals_to("2A", 42.0f, Integer::Base::Hexadecimal);
assert_integer_evals_to("42", 42.0f, Integer::Base::Decimal);
}
//Serialize
static inline void assert_integer_serializes_to(const Integer i, const char * serialization, Integer::Base base = Integer::Base::Decimal) {
char buffer[500];
i.serialize(buffer, 500, base);
quiz_assert(strcmp(buffer, serialization) == 0);
}
QUIZ_CASE(poincare_integer_serialize) {
assert_integer_serializes_to(Integer(-2), "-2");
assert_integer_serializes_to(Integer("2345678909876"), "2345678909876");
assert_integer_serializes_to(Integer("-2345678909876"), "-2345678909876");
assert_integer_serializes_to(Integer(9), "0b1001", Integer::Base::Binary);
assert_integer_serializes_to(Integer(9131), "0x23AB", Integer::Base::Hexadecimal);
assert_integer_serializes_to(Integer(123), "123", Integer::Base::Decimal);
assert_integer_serializes_to(Integer("-2345678909876"), "-2345678909876");
assert_integer_serializes_to(MaxInteger(), MaxIntegerString());
assert_integer_serializes_to(OverflowedInteger(), Infinity::Name());
}
// Euclidian Division
void assert_division_computes_to(int n, int m, const char * div) {
assert_expression_serialize_to(Integer::CreateEuclideanDivision(Integer(n), Integer(m)), div);
}
QUIZ_CASE(poincare_integer_euclidian_division) {
assert_division_computes_to(47, 8, "47=8×5+7");
assert_division_computes_to(1, 5, "1=5×0+1");
assert_division_computes_to(12, 4, "12=4×3+0");
assert_division_computes_to(-33, 7, "-33=7×(-5)+2");
assert_division_computes_to(-28, 101, "-28=101×(-1)+73");
assert_division_computes_to(-40, 2, "-40=2×(-20)+0");
}
void assert_mixed_fraction_computes_to(int n, int m, const char * frac) {
assert_expression_serialize_to(Integer::CreateMixedFraction(Integer(n), Integer(m)), frac);
}
QUIZ_CASE(poincare_integer_mixed_fraction) {
assert_mixed_fraction_computes_to(47, 8, "5+7/8");
assert_mixed_fraction_computes_to(1, 5, "0+1/5");
assert_mixed_fraction_computes_to(-33, 7, "-4-5/7");
assert_mixed_fraction_computes_to(-28, 101, "0-28/101");
}