5 //XXX Pensado para andar con unsigned's (si anda con otra cosa es casualidad =)
7 template < typename T >
12 typedef T atomic_type;
13 typedef typename std::vector< T > chunk_type;
14 typedef typename chunk_type::size_type size_type;
15 typedef typename chunk_type::iterator iterator;
16 typedef typename chunk_type::const_iterator const_iterator;
19 number(): chunk(1, 0) {}
20 number(atomic_type* buf, size_type len): chunk(buf, buf + len)
22 number(atomic_type* buf)
23 { while (*buf) chunk.push_back(*(buf++)); fix_empty(); }
24 number(atomic_type n): chunk(1, n) {}
25 // TODO constructor a partir de string.
28 number& operator++ () { if (!++chunk[0]) carry(1); return *this; }
29 number& operator+= (const number& n)
33 size_type fin = std::min(chunk.size(), n.chunk.size());
34 for (size_type i = ini; i < fin; ++i)
36 chunk[i] += n.chunk[i] + c;
37 if (chunk[i] || (!n.chunk[i] && !c)) c = 0; // OK
38 else c = 1; // Overflow
40 if (chunk.size() >= n.chunk.size()) // No hay más
42 if (c) carry(fin); // Propago carry
48 for (size_type i = ini; i < fin; ++i)
50 chunk.push_back(n.chunk[i] + c); // Agrego nuevo átomo
51 if (chunk[i] || !c) c = 0; // OK
52 else c = 1; // Overflow
54 if (c) chunk.push_back(1); // Último carry
57 atomic_type& operator[] (size_type i) { return chunk[i]; }
60 iterator begin() { return chunk.begin(); }
61 iterator end() { return chunk.end(); }
62 const_iterator begin() const { return chunk.begin(); }
63 const_iterator end() const { return chunk.end(); }
70 void fix_empty() { if (!chunk.size()) chunk.push_back(0); }
71 void carry(size_type i)
76 if (!chunk[i]) carry(i+1); // Overflow
78 else chunk.push_back(1);
82 template < typename T >
83 number< T > operator+ (const number< T >& n1, const number< T >& n2)
90 template < typename T >
91 std::ostream& operator<< (std::ostream& os, const number< T >& n)
93 // FIXME sacar una salida bonita en ASCII =)
94 std::copy(n.begin(), n.end(), std::ostream_iterator< T >(os, " "));