From: Leandro Lucarella Date: Tue, 27 Sep 2005 07:57:21 +0000 (+0000) Subject: Estructura inicial y tipo básico. X-Git-Tag: Entrega_1~71 X-Git-Url: https://git.llucax.com/z.facultad/75.29/dale.git/commitdiff_plain/f1aa8ccb4ffc3b12108475fb79492d0918c120b1 Estructura inicial y tipo básico. Mini estructura de directorios con lo básico. Hay un tipo parametrizado number< T > (diseñado para unsigned's, si anda con otra cosa es casualidad) que ya tiene implementada la suma y una forma _muy_ precaria de imprimirse. Lo básico como para empezar a trabajar. --- f1aa8ccb4ffc3b12108475fb79492d0918c120b1 diff --git a/src/number.h b/src/number.h new file mode 100644 index 0000000..82c6067 --- /dev/null +++ b/src/number.h @@ -0,0 +1,97 @@ +#include +#include +#include + +//XXX Pensado para andar con unsigned's (si anda con otra cosa es casualidad =) + +template < typename T > +struct number +{ + + // Tipos + typedef T atomic_type; + typedef typename std::vector< T > chunk_type; + typedef typename chunk_type::size_type size_type; + typedef typename chunk_type::iterator iterator; + typedef typename chunk_type::const_iterator const_iterator; + + // Constructores + number(): chunk(1, 0) {} + number(atomic_type* buf, size_type len): chunk(buf, buf + len) + { fix_empty(); } + number(atomic_type* buf) + { while (*buf) chunk.push_back(*(buf++)); fix_empty(); } + number(atomic_type n): chunk(1, n) {} + // TODO constructor a partir de string. + + // Operadores + number& operator++ () { if (!++chunk[0]) carry(1); return *this; } + number& operator+= (const number& n) + { + atomic_type c = 0; + size_type ini = 0; + size_type fin = std::min(chunk.size(), n.chunk.size()); + for (size_type i = ini; i < fin; ++i) + { + chunk[i] += n.chunk[i] + c; + if (chunk[i] || (!n.chunk[i] && !c)) c = 0; // OK + else c = 1; // Overflow + } + if (chunk.size() >= n.chunk.size()) // No hay más + { + if (c) carry(fin); // Propago carry + return *this; + } + // Hay más + ini = fin; + fin = n.chunk.size(); + for (size_type i = ini; i < fin; ++i) + { + chunk.push_back(n.chunk[i] + c); // Agrego nuevo átomo + if (chunk[i] || !c) c = 0; // OK + else c = 1; // Overflow + } + if (c) chunk.push_back(1); // Último carry + return *this; + } + atomic_type& operator[] (size_type i) { return chunk[i]; } + + // Iteradores + iterator begin() { return chunk.begin(); } + iterator end() { return chunk.end(); } + const_iterator begin() const { return chunk.begin(); } + const_iterator end() const { return chunk.end(); } + + private: + // Atributos + chunk_type chunk; + + // Helpers + void fix_empty() { if (!chunk.size()) chunk.push_back(0); } + void carry(size_type i) + { + if (chunk.size() > i) + { + ++chunk[i]; + if (!chunk[i]) carry(i+1); // Overflow + } + else chunk.push_back(1); + } +}; + +template < typename T > +number< T > operator+ (const number< T >& n1, const number< T >& n2) +{ + number< T > tmp = n1; + tmp += n2; + return tmp; +} + +template < typename T > +std::ostream& operator<< (std::ostream& os, const number< T >& n) +{ + // FIXME sacar una salida bonita en ASCII =) + std::copy(n.begin(), n.end(), std::ostream_iterator< T >(os, " ")); + return os; +} + diff --git a/tests/Makefile b/tests/Makefile new file mode 100644 index 0000000..09d0ac9 --- /dev/null +++ b/tests/Makefile @@ -0,0 +1,15 @@ + +# Opciones para el compilador C++. +CXXFLAGS = -Wall -ggdb -ansi -pedantic -DDEBUG -fno-inline + + +# REGLAS +######### + +.PHONY: clean + +o_files = $(patsubst %.$(extension),%.o,$(fuentes)) + +clean: + @$(RM) -fv *.o $(target) + diff --git a/tests/number.cpp b/tests/number.cpp new file mode 100644 index 0000000..bee9976 --- /dev/null +++ b/tests/number.cpp @@ -0,0 +1,16 @@ +#include +#include "../src/number.h" + +int main() +{ + //unsigned buf[5] = { 0xfffffffe, 0xffffffff, 0xffffffff, 0xffffffff, 0 }; + //unsigned buf[3] = { 0xffffffff, 0x1, 0 }; + number< unsigned > nu = 0xffffffff; + //number< unsigned > nu2(nu); + number< unsigned > nu2 = 1u; + std::cout << "nu = " << nu << "\n\n"; + std::cout << "nu2 = " << nu2 << "\n\n"; + std::cout << "nu + nu2 = " << nu + nu2 << "\n\n"; + return 0; +} +