changed: UInt::FromString(...) skips the input digits when the value is too big

added: tests: addtwoints (only 32bit)


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@95 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
Tomasz Sowa 2009-02-16 17:57:34 +00:00
parent 1d81dc75ff
commit c7c859fc76
5 changed files with 161 additions and 73 deletions

View File

@ -46,6 +46,7 @@ const char uint_tests_file[] = "tests.uint32";
bool test_lahf() bool test_lahf()
{ {
#ifdef TTMATH_PLATFORM64 #ifdef TTMATH_PLATFORM64

View File

@ -6,8 +6,6 @@ add 32 0 1 1 2 0
add 32 0 2342234 3563456 5905690 0 add 32 0 2342234 3563456 5905690 0
add 32 0 254455 3453435 3707890 0 add 32 0 254455 3453435 3707890 0
add 32 0 4294967295 0 4294967295 0 add 32 0 4294967295 0 4294967295 0
# testing a carry for add
add 32 32 4294967295 1 0 1 add 32 32 4294967295 1 0 1
add 32 32 4294967295 0 4294967295 0 add 32 32 4294967295 0 4294967295 0
add 64 64 18446744073709551615 1 0 1 add 64 64 18446744073709551615 1 0 1
@ -49,50 +47,25 @@ addint 192 192 64 627710173538668076383578942320766641610
# AddTwoInts
# a the value
# c lower word
# b higher word
# index - index of the lower (c) word
# if there is a carry the result is skipped
# min_bits max_bits bits_per_int a b(int) c(int) index result carry
addtwoints 64 0 32 0 0 0 0 0 0
addtwoints 64 0 32 23542345 3453245 2356252356 0 14831576719870221 0
addtwoints 64 64 32 4563456879824345332 3453245255 3673623543 0 0 1
addtwoints 96 0 32 345345634564352344231 1231354534 345324551 1 22714482299528678798871855271 0
addtwoints 96 96 32 33333336690445123453645645123 4241542514 145235414 1 0 1
addtwoints 128 0 32 921345787234870984751756 2356245656 3423623455 2 186681013820253010515426931265335245452 0
addtwoints 128 128 32 259817508127340892734075234234345345346 3452345324 452354345 2 0 1
addtwoints 160 0 32 458674036702857083457018457034 435236456 1451234242 1 466702732224470435083940719562 0
addtwoints 160 0 32 258672084570198475012875019876674534523452543562 935245345 736765636 3 576919584276960743542382023227664277469907669578 0
addtwoints 192 0 32 2398670187501982374012837086745045 3253453245 234567536 4 4754927244626858434362642830810490464530603685767816794581 0
addtwoints 192 192 32 1734564564356435667546738087098769876387468736123143453646 3456345245 3256347435 4 0 1

View File

@ -46,24 +46,47 @@ void UIntTest::set_file_name(const std::string & f)
} }
uuint UIntTest::read_uint() bool UIntTest::read_uint(uuint & result)
{ {
uuint result = 0; UInt<1> temp;
skip_white_characters();
for( ; *pline>='0' && *pline<='9' ; ++pline ) int c = temp.FromString(pline, 10, &pline);
result = result * 10 + (*pline - '0');
return result; result = temp.ToUInt();
if( c )
{
std::cerr << " carry from reading uint" << std::endl;
return false;
}
return true;
} }
template<uuint type_size>
bool UIntTest::read_uint(UInt<type_size> & result)
{
int c = result.FromString(pline, 10, &pline);
if( c )
{
std::cerr << " carry from UInt<>::FromString()" << std::endl;
return false;
}
return true;
}
bool UIntTest::check_minmax_bits(int type_size) bool UIntTest::check_minmax_bits(int type_size)
{ {
int min_bits = read_uint(); uuint min_bits;
int max_bits = read_uint(); uuint max_bits;
read_uint(min_bits);
read_uint(max_bits);
if( min_bits != 0 && type_size * TTMATH_BITS_PER_UINT < (unsigned int)min_bits ) if( min_bits != 0 && type_size * TTMATH_BITS_PER_UINT < (unsigned int)min_bits )
return false; return false;
@ -80,7 +103,9 @@ bool UIntTest::check_minmax_bits_bitperint(int type_size)
if( !check_minmax_bits(type_size) ) if( !check_minmax_bits(type_size) )
return false; return false;
int bits = read_uint(); uuint bits;
read_uint(bits);
if( TTMATH_BITS_PER_UINT != bits ) if( TTMATH_BITS_PER_UINT != bits )
return false; return false;
@ -126,7 +151,27 @@ return ok;
} }
template<uuint type_size>
bool UIntTest::check_result_or_carry(const ttmath::UInt<type_size> & result, const ttmath::UInt<type_size> & new_result,
int carry, int new_carry)
{
if( new_carry != carry )
{
std::cerr << "Incorrect carry: " << new_carry << " (expected: " << carry << ")" << std::endl;
return false;
}
if( new_carry == 1 )
return true;
if( new_result != result )
{
std::cerr << "Incorrect result: " << new_result << " (expected: " << result << ")" << std::endl;
return false;
}
return true;
}
@ -138,10 +183,12 @@ void UIntTest::test_add()
if( !check_minmax_bits(type_size) ) if( !check_minmax_bits(type_size) )
return; return;
a.FromString(pline, 10, &pline); read_uint(a);
b.FromString(pline, 10, &pline); read_uint(b);
result.FromString(pline, 10, &pline); read_uint(result);
int carry = read_uint();
uuint carry;
read_uint(carry);
std::cerr << '[' << row << "] Add<" << type_size << ">: "; std::cerr << '[' << row << "] Add<" << type_size << ">: ";
@ -164,11 +211,14 @@ void UIntTest::test_addint()
if( !check_minmax_bits_bitperint(type_size) ) if( !check_minmax_bits_bitperint(type_size) )
return; return;
a.FromString(pline, 10, &pline); uuint b, index, carry;
uuint b = read_uint();
uuint index = read_uint(); read_uint(a);
result.FromString(pline, 10, &pline); read_uint(b);
int carry = read_uint(); read_uint(index);
read_uint(result);
read_uint(carry);
std::cerr << '[' << row << "] AddInt<" << type_size << ">: "; std::cerr << '[' << row << "] AddInt<" << type_size << ">: ";
@ -182,6 +232,44 @@ void UIntTest::test_addint()
std::cerr << "ok" << std::endl; std::cerr << "ok" << std::endl;
} }
template<uuint type_size>
void UIntTest::test_addtwoints()
{
UInt<type_size> a, result, new_result;
if( !check_minmax_bits_bitperint(type_size) )
return;
std::cerr << '[' << row << "] AddTwoInts<" << type_size << ">: ";
uuint b, c, index, carry;
read_uint(a);
read_uint(b);
read_uint(c);
read_uint(index);
read_uint(result);
read_uint(carry);
if( !check_end() )
return;
if( index >= type_size - 1 )
{
std::cerr << "index too large" << std::endl;
return;
}
new_result = a;
int new_carry = new_result.AddTwoInts(b, c, index);
if( check_result_or_carry(result, new_result, carry, new_carry) )
std::cerr << "ok" << std::endl;
}
int UIntTest::upper_char(int c) int UIntTest::upper_char(int c)
{ {
@ -242,6 +330,7 @@ return true;
} }
void UIntTest::test_method() void UIntTest::test_method()
{ {
const char * p = pline; const char * p = pline;
@ -272,6 +361,19 @@ const char * p = pline;
pline = p; test_addint<9>(); pline = p; test_addint<9>();
} }
else else
if( method == "ADDTWOINTS" )
{
pline = p; test_addtwoints<1>();
pline = p; test_addtwoints<2>();
pline = p; test_addtwoints<3>();
pline = p; test_addtwoints<4>();
pline = p; test_addtwoints<5>();
pline = p; test_addtwoints<6>();
pline = p; test_addtwoints<7>();
pline = p; test_addtwoints<8>();
pline = p; test_addtwoints<9>();
}
else
{ {
std::cerr << '[' << row << "] "; std::cerr << '[' << row << "] ";
std::cerr << "method " << method << " is not supported" << std::endl; std::cerr << "method " << method << " is not supported" << std::endl;

View File

@ -71,12 +71,21 @@ public:
void go(); void go();
bool read_uint(uuint & result);
template<uuint type_size>
bool read_uint(UInt<type_size> & result);
template<uuint type_size> void test_add(); template<uuint type_size> void test_add();
template<uuint type_size> void test_addint(); template<uuint type_size> void test_addint();
template<uuint type_size> void test_addtwoints();
template<uuint type_size> bool check_result_carry(const ttmath::UInt<type_size> & result, const ttmath::UInt<type_size> & new_result, template<uuint type_size> bool check_result_carry(const ttmath::UInt<type_size> & result, const ttmath::UInt<type_size> & new_result,
int carry, int new_carry); int carry, int new_carry);
template<uuint type_size> bool check_result_or_carry(const ttmath::UInt<type_size> & result, const ttmath::UInt<type_size> & new_result,
int carry, int new_carry);
int upper_char(int c); int upper_char(int c);
bool is_white(int c); bool is_white(int c);
@ -84,7 +93,7 @@ void skip_white_characters();
bool read_method(); bool read_method();
void test_method(); void test_method();
bool check_line(); bool check_line();
uuint read_uint();
bool check_minmax_bits(int type_size); bool check_minmax_bits(int type_size);
bool check_minmax_bits_bitperint(int type_size); bool check_minmax_bits_bitperint(int type_size);
bool check_end(); bool check_end();

View File

@ -3119,12 +3119,15 @@ public:
"12foo" will be translated to 12 too "12foo" will be translated to 12 too
existing first white characters will be ommited existing first white characters will be ommited
if the value from s is too large the rest digits will be skipped
*/ */
uint FromString(const char * s, uint b = 10, const char ** after_source = 0) uint FromString(const char * s, uint b = 10, const char ** after_source = 0)
{ {
UInt<value_size> base( b ); UInt<value_size> base( b );
UInt<value_size> temp; UInt<value_size> temp;
sint z; sint z;
uint c = 0;
SetZero(); SetZero();
temp.SetZero(); temp.SetZero();
@ -3136,23 +3139,23 @@ public:
if( b<2 || b>16 ) if( b<2 || b>16 )
return 1; return 1;
for( ; (z=CharToDigit(*s, b)) != -1 ; ++s) for( ; (z=CharToDigit(*s, b)) != -1 ; ++s)
{ {
temp.table[0] = z; if( c == 0 )
if( Mul(base) || Add(temp) ) // first is called Mul() and next Add()
{ {
if( after_source ) temp.table[0] = z;
*after_source = s;
return 1; c += Mul(base);
c += Add(temp);
} }
} }
if( after_source ) if( after_source )
*after_source = s; *after_source = s;
return 0;
return (c==0)? 0 : 1;
} }