#include <stdint.h>
#include "aritmetica.hpp"
uint64_t to_u64(double n)
{
uint64_t *p;
p = (uint64_t *) &n;
return *p;
}
uint64_t to_u64(numero n)
{
return to_u64(n.to_double());
}
double to_double(uint64_t n)
{
double *p;
p = (double *) &n;
return *p;
}
double trunc(int prec, double n)
{
/* Sabemos que el double tiene 64 bits en total, de los cuales se usan
* 52 para la mantisa. Para recortar, dejamos en 0 todo lo que excede
* a la precision pedida, aplicando una máscara. */
/* Armamos la máscara */
uint64_t mask = 0xFFFFffffFFFFffffLLU;
mask = mask << (52 - prec);
uint64_t t = to_u64(n) & mask;
return to_double(t);
}
double round_up(int prec, double n)
{
double round = trunc(prec + 1, n) - trunc(prec, n);
return trunc(prec, n + round);
}
/*
* Clase número
*/
/* Por default usamos truncamiento como metodo de aproximacion */
double (*numero::aprox_m) (int prec, double n) = trunc;
numero::numero(int prec, double real)
{
this->prec = prec;
this->real = numero::aprox_m(prec, real);
}
int numero::get_prec() const
{
return this->prec;
}
/* Todas las operaciónes son iguales, por lo que armamos una macro para
* crearlas y ahorrarnos el copy-paste */
#define DEF_OP(OP) \
numero numero::operator OP (const numero &b) const \
{ \
return numero(this->prec, \
numero::aprox_m(this->prec, this->real) \
OP \
numero::aprox_m(this->prec, b.real)); \
} \
\
numero numero::operator OP (const double &b) const \
{ \
return numero(this->prec, \
numero::aprox_m(this->prec, this->real) \
OP \
numero::aprox_m(this->prec, b)); \
} \
\
numero operator OP (const double &a, const numero &b) \
{ \
return numero(b.get_prec(), \
numero::aprox_m(b.get_prec(), a) \
OP \
b.to_double()); \
}
DEF_OP(+)
DEF_OP(-)
DEF_OP(*)
DEF_OP(/)
numero numero::operator = (double n)
{
this->real = trunc(this->prec, n);
return *this;
}
numero numero::operator = (numero n)
{
this->prec = n.prec;
this->real = n.real;
return *this;
}
bool numero::operator == (numero n)
{
return (n.real == this->real);
}
//numero::operator double() const
//{
// return this->real;
//}
double numero::to_double() const
{
return this->real;
}