// borrow)
void borrow(size_type i)
{
- if (chunk.size() >= i)
+ // para poder pedir prestado debo tener uno a la izquierda
+ assert (chunk.size() >= i);
+
+ if (chunk[i] == 0)
{
- if (chunk[i] == 0)
- {
- borrow(i+1); // Overflow, pido prestado
- chunk[i] = ~((N)0); //quedo con el valor máximo
- }
- else
- {
- --chunk[i]; //tengo para dar, pero pierdo uno yo
- }
+ borrow(i+1); // Overflow, pido prestado
+ chunk[i] = ~((N)0); //quedo con el valor máximo
+ }
+ else
+ {
+ --chunk[i]; //tengo para dar, pero pierdo uno yo
}
- //else ERROR, están haciendo a-b con a>b
}
// Verifica si es un número par
bool es_impar() const
// si no alcanza para restar pido prestado
if ((minuend.chunk[i] < subtrahend.chunk[i]))
{
- minuend.borrow(i);
+ // no puedo pedir si soy el más significativo ...
+ assert (i != fin);
+
+ // le pido uno al que me sigue
+ minuend.borrow(i+1);
}
- // resto el chunk i-ésimo
- minuend.chunk[i] -= subtrahend.chunk[i];
+ // es como hacer 24-5: el 4 pide prestado al 2 (borrow(i+1)) y después
+ // se hace 4 + (9-5) + 1
+
+ minuend.chunk[i] += (~((N)0) - subtrahend.chunk[i]) + 1;
}
//retorno el minuendo ya restado
return tmp;
}
-template < typename N, typename E >
-std::ostream& operator<< (std::ostream& os, const number< N, E >& n)
+template < typename NN, typename EE >
+std::ostream& operator<< (std::ostream& os, const number< NN, EE >& n)
{
// FIXME sacar una salida bonita en ASCII =)
if (n.sign == positive)
os << "+ ";
else
os << "- ";
- for (typename number< N, E >::const_reverse_iterator i = n.chunk.rbegin();
+ for (typename number< NN, EE >::const_reverse_iterator i = n.chunk.rbegin();
i != n.chunk.rend(); ++i)
- os << std::setfill('0') << std::setw(sizeof(N) * 2) << std::hex
+ os << std::setfill('0') << std::setw(sizeof(NN) * 2) << std::hex
<< *i << " ";
return os;
}
int main()
{
#if 0
- unsigned buf[5] = { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0 };
+ unsigned long buf[5] = { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0 };
//unsigned buf[3] = { 0xffffffff, 0x1, 0 };
number<> nu(buf, 4);
//number< unsigned > nu2(nu);
#if 0
number< unsigned > nu = 0xffffffff;
- std::cout << "nu = " << nu << "\n\n";
+ std::cout << "nu = " << nu ;
nu << 5;
- std::cout << "nu = " << nu << "\n\n";
+ std::cout << "nu = " << nu ;
- number<> n1 = 0x00000000;
- number<> n2 = 0x00000000;
+ number<> n1 = 0xFFFFFFFF;
+ number<> n2 = 0xFFFFFFFF;
- n2 += 1;
+ n1 += 1;
- n1 <<= 1;
- n2 <<= 1;
+/* for (int k = 0; k < 100; k++)
+ {
+ n1 += (unsigned) rand() * k;
+ n2 += (unsigned) rand() * k;
+ }
+*/
+
+// n1 <<= 1;
+// n2 <<= 1;
if (n1 < n2)
std::cout << "n1 es menor que n2\n";
std::cout << "n1-n2: " << n1 ;
#endif
+#if 1
uint32_t buf[] = { 0x00000040, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 };
- number<> nu(buf, 8);
+ number<> nu(buf, 8, negative);
number<> nu2 = 0x2;
- std::cout << "nu = " << nu << "\n\n";
- std::cout << "nu2 = " << nu2 << "\n\n";
- std::cout << "nu * nu2 = " << naif(nu, nu2) << "\n\n";
+ std::cout << "nu = " << nu ;
+ std::cout << "\n";
+ std::cout << "nu2 = " << nu2 ;
+ std::cout << "\n";
+ std::cout << "nu * nu2 = " << naif(nu, nu2) ;
+ std::cout << "\n";
+ std::cout << "nu + nu2 = " << nu + nu2 ;
+ std::cout << "\n";
+ std::cout << "nu - nu2 = " << nu - nu2 ;
+
+#endif
+
+ number<> h = 0x10000000;
+ h<<=1;
+ h += 0xfffffffc;
+ h<<=1;
+ h += 0xffffffff;
+ h<<=1;
+ h += 0x00000002;
+ number<> d = 0;
+ number<> m = 0xfffffffe;
+ m<<=1;
+ m += 0xffffffff;
+ m<<=1;
+ m += 0x00000001;
+
+ std::cout << "h: " << h ;
+ std::cout << "\n";
+ std::cout << "d: " << d ;
+ std::cout << "\n";
+ std::cout << "m: " << m ;
+ std::cout << "\n";
+
+ number<> a = h - d - m;
+
+ std::cout << "h-d-m: " << a ;
+
return 0;
}