]> git.llucax.com Git - z.facultad/75.29/dale.git/commitdiff
Estructura inicial y tipo básico.
authorLeandro Lucarella <luca@llucax.hn.org>
Tue, 27 Sep 2005 07:57:21 +0000 (07:57 +0000)
committerLeandro Lucarella <luca@llucax.hn.org>
Tue, 27 Sep 2005 07:57:21 +0000 (07:57 +0000)
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.

src/number.h [new file with mode: 0644]
tests/Makefile [new file with mode: 0644]
tests/number.cpp [new file with mode: 0644]

diff --git a/src/number.h b/src/number.h
new file mode 100644 (file)
index 0000000..82c6067
--- /dev/null
@@ -0,0 +1,97 @@
+#include <vector>
+#include <algorithm>
+#include <iterator>
+
+//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 (file)
index 0000000..09d0ac9
--- /dev/null
@@ -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 (file)
index 0000000..bee9976
--- /dev/null
@@ -0,0 +1,16 @@
+#include <iostream>
+#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;
+}
+