ParanoidNumber & ParanoidNumber::operator+=(const ParanoidNumber & a)
{
-
if (m_next_factor == NULL && a.Floating())
{
if (ParanoidOp<digit_t>(m_value, a.m_value, ADD))
for (ParanoidNumber * a = this; a != NULL; a = a->m_next_term)
{
ParanoidNumber * b = a->m_next_term;
- if (a->m_next_factor != NULL)
+ if (a->m_next_factor != NULL && !a->m_next_factor->Floating())
{
continue;
}
{
//Debug("Simplify factors of %s", b->Str().c_str());
b->SimplifyFactors();
- if (b->m_next_factor != NULL)
+ if (b->m_next_factor != NULL && !b->m_next_factor->Floating())
{
bprev = b;
b = b->m_next_term;
continue;
}
+
bool simplify = false;
- simplify = ParanoidOp<digit_t>(a->m_value, b->Head<digit_t>(), ADD);
+ if (a->m_next_factor != NULL || b->m_next_factor != NULL)
+ {
+ digit_t aa(a->Head<digit_t>());
+ digit_t ab = (a->m_next_factor != NULL) ? a->m_next_factor->Head<digit_t>() : 1;
+ digit_t bc(b->Head<digit_t>());
+ digit_t bd = (b->m_next_factor != NULL) ? b->m_next_factor->Head<digit_t>() : 1;
+ Optype aop = (a->m_next_factor != NULL) ? a->m_next_factor->m_op : DIVIDE;
+ Optype cop = (b->m_next_factor != NULL) ? b->m_next_factor->m_op : DIVIDE;
+ simplify = CombineTerms<digit_t>(aa, aop, ab, bc, cop, bd);
+ if (simplify)
+ {
+ a->m_value = aa;
+ if (a->m_next_factor != NULL)
+ a->m_next_factor->m_value = ab;
+ else if (ab != 1)
+ {
+ a->m_next_factor = b->m_next_factor;
+ b->m_next_factor = NULL;
+ a->m_next_factor->m_value = ab;
+ }
+ }
+ }
+ else
+ {
+ simplify = ParanoidOp<digit_t>(a->m_value, b->Head<digit_t>(), ADD);
+ }
if (simplify)
{
bprev->m_next_term = b->m_next_term;
#include "log.h"
#include <fenv.h>
-#define PARANOID_DIGIT_T int8_t // we could theoretically replace this with a template
+#define PARANOID_DIGIT_T float // we could theoretically replace this with a template
// but let's not do that...
namespace IPDF
T a(aa); T b(bb); T c(cc); T d(dd);
if (aop == MULTIPLY && cop == MULTIPLY) // a*b + c*d
{
+
if ((ParanoidOp<T>(c, b, DIVIDE) || ParanoidOp(d, b, DIVIDE))
&& TrustingOp<T>(c, d, MULTIPLY) && TrustingOp<T>(a,c,ADD)
&& TrustingOp<T>(a, b, MULTIPLY)) // (a + (cd)/b) * b
}
else if (aop == DIVIDE && cop == DIVIDE)
{
+
+
if (TrustingOp<T>(a, d, MULTIPLY) && TrustingOp<T>(c, b, MULTIPLY)
&& TrustingOp<T>(a, c, ADD) && TrustingOp<T>(b, d, MULTIPLY))
{
break;
}
- cout << Double(c) << '\n';
+ //cout << Double(c) << '\n';
+ printf("%.40lf\n", Double(c));
}
}
Debug("FLT_EPSILON = %.40f", FLT_EPSILON);
Debug("Sizeof ParanoidNumber::digit_t is %u", sizeof(ParanoidNumber::digit_t));
Debug("Sizeof ParanoidNumber is %u", sizeof(ParanoidNumber));
+ Debug("Sizeof double is %u", sizeof(double));
+ Debug("Sizeof ParanoidNumber* %u", sizeof(ParanoidNumber*));
string token("");
cin >> token;
Debug("a is: %s", a.Str().c_str());
Debug("a as double: %.40f\n", a.ToDouble());
+ Debug("a as float: %.40f\n", a.ToFloat());
+ Debug("a as int64_t: %ld\n", a.Convert<int64_t>());
Debug("floats give: %.40f\n", fa);
Debug("double gives: %.40f\n", da);
Error("As PN: %lf %c %lf", olda.ToDouble(), opch[op], b.ToDouble());
Error("PN String: %s", a.Str().c_str());
Error("Diff is %.40lf", diff);
+ Error("LONG double gives %.40llf", lda);
Fatal("%.40lf, expected aboout %.40lf", a.ToDouble(), da);