diff --git a/tests/Makefile b/tests/Makefile new file mode 100644 index 0000000..4492635 --- /dev/null +++ b/tests/Makefile @@ -0,0 +1,31 @@ +CC = g++ +o = main.o uinttest.o +CFLAGS = -Wall -pedantic +ttmath = /d/roboczy/prog/ttmath +name = tests + + + +.SUFFIXES: .cpp .o + +.cpp.o: + $(CC) -c $(CFLAGS) -I$(ttmath) $< + + +all: $(name) + + +$(name): $(o) + $(CC) -o $(name) $(CFLAGS) -I$(ttmath) $(o) + + +main.o: main.cpp uinttest.h +uinttest.o: uinttest.cpp uinttest.h + + +clean: + rm -f *.o + rm -f $(name) + rm -f $(name).exe + + diff --git a/tests/main.cpp b/tests/main.cpp new file mode 100644 index 0000000..b052c4a --- /dev/null +++ b/tests/main.cpp @@ -0,0 +1,70 @@ +/* + * This file is a part of TTMath Mathematical Library + * and is distributed under the (new) BSD licence. + * Author: Tomasz Sowa + */ + +/* + * Copyright (c) 2006-2008, Tomasz Sowa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name Tomasz Sowa nor the names of contributors to this + * project may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include +#include +#include "uinttest.h" + + +const char uint_tests_file[] = "tests.uint32"; + + +void test_uint() +{ + UIntTest test; + + test.set_file_name(uint_tests_file); + test.go(); +} + + + +int main() +{ +using namespace ttmath; + + + + test_uint(); + + + + + +return 0; +} diff --git a/tests/tests.uint32 b/tests/tests.uint32 new file mode 100644 index 0000000..c890d97 --- /dev/null +++ b/tests/tests.uint32 @@ -0,0 +1,63 @@ +# Add + +# min_bits max_bits a b result carry +add 32 0 0 0 0 0 +add 32 0 1 1 2 0 +add 32 0 2342234 3563456 5905690 0 +add 32 0 254455 3453435 3707890 0 +add 32 0 4294967295 0 4294967295 0 + +# testing a carry for add +add 32 32 4294967295 1 0 1 +add 32 32 4294967295 0 4294967295 0 +add 64 64 18446744073709551615 1 0 1 +add 64 64 18446744073709551615 0 18446744073709551615 0 +add 96 96 79228162514264337593543950335 1 0 1 +add 96 96 79228162514264337593543950335 0 79228162514264337593543950335 0 +add 128 128 340282366920938463463374607431768211455 1 0 1 +add 128 128 340282366920938463463374607431768211455 0 340282366920938463463374607431768211455 0 +add 160 160 1461501637330902918203684832716283019655932542975 1 0 1 +add 160 160 1461501637330902918203684832716283019655932542975 0 1461501637330902918203684832716283019655932542975 0 +add 192 192 6277101735386680763835789423207666416102355444464034512895 1 0 1 +add 192 192 6277101735386680763835789423207666416102355444464034512895 0 6277101735386680763835789423207666416102355444464034512895 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/uinttest.cpp b/tests/uinttest.cpp new file mode 100644 index 0000000..b696b09 --- /dev/null +++ b/tests/uinttest.cpp @@ -0,0 +1,241 @@ +/* + * This file is a part of TTMath Mathematical Library + * and is distributed under the (new) BSD licence. + * Author: Tomasz Sowa + */ + +/* + * Copyright (c) 2006-2008, Tomasz Sowa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name Tomasz Sowa nor the names of contributors to this + * project may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include "uinttest.h" + + + +void UIntTest::set_file_name(const std::string & f) +{ + file_name = f; +} + + +int UIntTest::read_int() +{ +int result = 0; + + skip_white_characters(); + + for( ; *pline>='0' && *pline<='9' ; ++pline ) + result = result * 10 + (*pline - '0'); + +return result; +} + + + +template +void UIntTest::test_add() +{ +using namespace ttmath; + + UInt a,b,result, new_result; + + int min_bits = read_int(); + int max_bits = read_int(); + + if( min_bits != 0 && type_size * TTMATH_BITS_PER_UINT < (unsigned int)min_bits ) + return; + + if( max_bits != 0 && type_size * TTMATH_BITS_PER_UINT > (unsigned int)max_bits ) + return; + + a.FromString(pline, 10, &pline); + b.FromString(pline, 10, &pline); + result.FromString(pline, 10, &pline); + int carry = read_int(); + + std::cerr << '[' << row << "] Add<" << type_size << ">: "; + + skip_white_characters(); + if( *pline!='#' && *pline!= 0 ) + { + std::cerr << "syntax error" << std::endl; + return; + } + + new_result = a; + int new_carry = new_result.Add(b); + bool ok = true; + + if( new_carry != carry ) + { + std::cerr << "Incorrect carry: " << new_carry << " (expected: " << carry << ")" << std::endl; + ok = false; + } + + if( new_result != result ) + { + std::cerr << "Incorrect result: " << new_result << " (expected: " << result << ")" << std::endl; + ok = false; + } + + if( ok ) + { + std::cerr << "ok" << std::endl; + } +} + + + + +int UIntTest::upper_char(int c) +{ + if( c>='a' && c<='z' ) + return c - 'a' + 'A'; + +return c; +} + + +bool UIntTest::is_white(int c) +{ + if( c==' ' || c=='\t' || c==13 ) + return true; + +return false; +} + + +void UIntTest::skip_white_characters() +{ + while( is_white(*pline) ) + ++pline; +} + + + +bool UIntTest::read_method() +{ + skip_white_characters(); + + if( *pline == '#' ) + return false; + + method.clear(); + + for(int c = upper_char(*pline) ; c>='A'&& c<='Z' ; c = upper_char(*pline) ) + { + method += c; + ++pline; + } + + if( method.empty() ) + { + skip_white_characters(); + if( *pline == 0 ) + return false; + else + { + std::cerr << '[' << row << "] "; + std::cerr << "syntax error" << std::endl; + return false; + } + } + + +return true; +} + + +void UIntTest::test_method() +{ +const char * p = pline; + + if( method == "ADD" ) + { + pline = p; test_add<1>(); + pline = p; test_add<2>(); + pline = p; test_add<3>(); + pline = p; test_add<4>(); + pline = p; test_add<5>(); + pline = p; test_add<6>(); + pline = p; test_add<7>(); + pline = p; test_add<8>(); + pline = p; test_add<9>(); + } + else + { + std::cerr << '[' << row << "] "; + std::cerr << "method " << method << " is not supported" << std::endl; + } +} + + +bool UIntTest::check_line() +{ + std::getline(file, line); + + pline = line.c_str(); + + if( read_method() ) + test_method(); + + + if( file.eof() ) + return false; + + +return true; +} + + + + +void UIntTest::go() +{ + file.open(file_name.c_str()); + + + if( !file ) + { + std::cerr << "I can't open the input file" << std::endl; + return; + } + + row = 1; + + while( check_line() ) + ++row; + +} + + + + diff --git a/tests/uinttest.h b/tests/uinttest.h new file mode 100644 index 0000000..bc4d649 --- /dev/null +++ b/tests/uinttest.h @@ -0,0 +1,90 @@ +/* + * This file is a part of TTMath Mathematical Library + * and is distributed under the (new) BSD licence. + * Author: Tomasz Sowa + */ + +/* + * Copyright (c) 2006-2008, Tomasz Sowa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name Tomasz Sowa nor the names of contributors to this + * project may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#ifndef headerfileuinttest +#define headerfileuinttest + +#include +#include +#include + +#include + + + + +class UIntTest +{ + + std::string file_name; + + // current line from the file + std::string line; + const char * pline; + + std::ifstream file; + + + std::string method; + + int row; + +public: + + void set_file_name(const std::string & f); + + void go(); + + template + void test_add(); + + +int upper_char(int c); +bool is_white(int c); +void skip_white_characters(); +bool read_method(); +void test_method(); +bool check_line(); +int read_int(); + + + +}; + + +#endif diff --git a/ttmath/ttmathuint.h b/ttmath/ttmathuint.h index 1a63eb8..01ae44a 100644 --- a/ttmath/ttmathuint.h +++ b/ttmath/ttmathuint.h @@ -265,9 +265,9 @@ public: xor eax,eax sub eax,[c] - lahf + lahf // flags -> AH (flags: SF ZF AF CF) PF? p: - sahf + sahf // AH -> flags (flags: SF ZF AF CF) PF? mov eax,[ebx] adc eax,[edx] mov [ebx],eax @@ -279,15 +279,12 @@ public: sub ecx,1 jnz p + // checking carry from the last word + // CF = bit 0 test ah,1 setnz al - - // - // movzx dword ptr [c],al - // movzx edx, al mov [c], edx - // pop edx pop ecx @@ -3095,7 +3092,7 @@ public: existing first white characters will be ommited */ - uint FromString(const char * s, uint b = 10) + uint FromString(const char * s, uint b = 10, const char ** after_source = 0) { UInt base( b ); UInt temp; @@ -3105,6 +3102,9 @@ public: temp.SetZero(); SkipWhiteCharacters(s); + if( after_source ) + *after_source = s; + if( b<2 || b>16 ) return 1; @@ -3112,13 +3112,18 @@ public: { temp.table[0] = z; - if( Mul(base) ) - return 1; + if( Mul(base) || Add(temp) ) // first is called Mul() and next Add() + { + if( after_source ) + *after_source = s; - if( Add(temp) ) return 1; + } } + if( after_source ) + *after_source = s; + return 0; }