1 #include "paranoidnumber.h"
11 int64_t ParanoidNumber::g_count = 0;
13 ParanoidNumber::ParanoidNumber(const char * str) : m_value(0), m_op(ADD), m_next_term(NULL), m_next_factor(NULL)
17 while (str[dp] != '\0' && str[dp] != '.')
22 while (str[end] != '\0')
26 for (int i = dp-1; i >= 0; --i)
28 ParanoidNumber b(str[i]-'0');
30 //Debug("m is %s", m.Str().c_str());
31 //Debug("Add %s", b.Str().c_str());
33 //Debug("Now at %s", Str().c_str());
37 for (int i = dp+1; i < end; ++i)
40 ParanoidNumber b(str[i]-'0');
41 //Debug("%s * %s", b.Str().c_str(), n.Str().c_str());
43 //Debug("b -> %s", b.Str().c_str());
44 //Debug("Add %s", b.Str().c_str());
46 //Debug("Now at %s", Str().c_str());
49 //Debug("Constructed {%s} from %s (%f)", Str().c_str(), str, ToDouble());
52 ParanoidNumber & ParanoidNumber::operator=(const ParanoidNumber & a)
58 if (a.m_next_term != NULL)
60 m_next_term = new ParanoidNumber(*(a.m_next_term));
62 if (a.m_next_factor != NULL)
64 m_next_factor = new ParanoidNumber(*(a.m_next_factor));
69 ParanoidNumber & ParanoidNumber::operator+=(const ParanoidNumber & a)
72 if (m_next_factor == NULL && a.Floating())
74 if (ParanoidOp<digit_t>(m_value, a.m_value, ADD))
80 ParanoidNumber * nt = m_next_term;
81 ParanoidNumber * nf = m_next_factor;
84 if (m_next_factor != NULL)
86 if (m_next_factor->m_op == MULTIPLY)
87 ca /= (*m_next_factor);
89 ca *= (*m_next_factor);
104 m_next_term = new ParanoidNumber(a, ADD);
105 ParanoidNumber * t = m_next_term;
106 while (t->m_next_term != NULL)
109 //Debug("Simplify {%s} after add", Str().c_str());
114 ParanoidNumber & ParanoidNumber::operator-=(const ParanoidNumber & a)
116 // this = v + t + (a)
118 if (m_next_factor == NULL && a.Floating())
120 if (ParanoidOp<digit_t>(m_value, a.m_value, ADD))
127 ParanoidNumber * nt = m_next_term;
128 ParanoidNumber * nf = m_next_factor;
130 ParanoidNumber ca(a, SUBTRACT);
131 if (m_next_factor != NULL)
133 if (m_next_factor->m_op == MULTIPLY)
134 ca /= (*m_next_factor);
136 ca *= (*m_next_factor);
140 m_next_factor = NULL;
151 m_next_term = new ParanoidNumber(a,SUBTRACT);
152 ParanoidNumber * t = m_next_term;
153 while (t->m_next_term != NULL)
159 //Debug("next term {%s}", m_next_term->Str().c_str());
161 //Debug("Simplify {%s} after sub", Str().c_str());
166 ParanoidNumber & ParanoidNumber::operator*=(const ParanoidNumber & a)
171 //Debug("{%s} *= {%s}", Str().c_str(), a.Str().c_str());
172 // this = (vf + t) * (a)
173 if (a.Floating() && ParanoidOp<digit_t>(m_value, a.m_value, MULTIPLY))
175 if (m_next_term != NULL)
176 m_next_term->operator*=(a);
181 ParanoidNumber * t = this;
182 while (t->m_next_factor != NULL)
183 t = t->m_next_factor;
184 t->m_next_factor = new ParanoidNumber(a, MULTIPLY);
186 if (m_next_term != NULL)
187 m_next_term->operator*=(a);
189 //Debug("Simplify {%s}", Str().c_str());
191 //Debug("Simplified to {%s}", Str().c_str());
196 ParanoidNumber & ParanoidNumber::operator/=(const ParanoidNumber & a)
201 if (a.Floating() && ParanoidOp<digit_t>(m_value, a.m_value, DIVIDE))
203 if (m_next_term != NULL)
204 m_next_term->operator/=(a);
209 //Debug("Called %s /= %s", Str().c_str(), a.Str().c_str());
210 // this = (vf + t) * (a)
211 ParanoidNumber * t = this;
212 while (t->m_next_factor != NULL)
214 t = t->m_next_factor;
216 t->m_next_factor = new ParanoidNumber(a, DIVIDE);
218 if (m_next_term != NULL)
219 m_next_term->operator/=(a);
227 void ParanoidNumber::SimplifyTerms()
230 //Debug("Simplify {%s}", Str().c_str());
231 if (m_next_term == NULL)
233 //Debug("No terms!");
237 for (ParanoidNumber * a = this; a != NULL; a = a->m_next_term)
239 ParanoidNumber * b = a->m_next_term;
240 if (a->m_next_factor != NULL)
245 ParanoidNumber * bprev = a;
248 //Debug("Simplify factors of %s", b->Str().c_str());
249 b->SimplifyFactors();
250 if (b->m_next_factor != NULL)
256 bool simplify = false;
257 simplify = ParanoidOp<digit_t>(a->m_value, b->Head<digit_t>(), ADD);
260 bprev->m_next_term = b->m_next_term;
261 b->m_next_term = NULL;
272 void ParanoidNumber::SimplifyFactors()
275 //Debug("Simplify {%s}", Str().c_str());
276 if (m_next_factor == NULL)
278 //Debug("No factors!");
282 for (ParanoidNumber * a = this; a != NULL; a = a->m_next_factor)
284 if ((a->m_op != ADD || a->m_op != SUBTRACT) && a->m_next_term != NULL)
287 ParanoidNumber * bprev = a;
288 ParanoidNumber * b = a->m_next_factor;
292 if (b->m_next_term != NULL)
295 b = b->m_next_factor;
300 if (a->m_op == DIVIDE)
302 op = (b->m_op == DIVIDE) ? MULTIPLY : DIVIDE;
305 if (ParanoidOp<digit_t>(a->m_value, b->m_value, op))
308 bprev->m_next_factor = b->m_next_factor;
309 b->m_next_factor = NULL;
314 b = b->m_next_factor;
319 void ParanoidNumber::Simplify()
325 string ParanoidNumber::Str() const
329 s << (double)m_value;
331 if (m_next_factor != NULL)
334 result += OpChar(m_next_factor->m_op);
335 if (m_next_factor->m_next_term != NULL)
336 result += "(" + m_next_factor->Str() + ")";
338 result += m_next_factor->Str();
345 if (m_next_term != NULL)
348 result += OpChar(m_next_term->m_op);
349 result += m_next_term->Str();
355 bool TrustingOp<float>(float & a, const float & b, Optype op)
357 feclearexcept(FE_ALL_EXCEPT);
373 return !fetestexcept(FE_ALL_EXCEPT);
377 bool TrustingOp<double>(double & a, const double & b, Optype op)
379 feclearexcept(FE_ALL_EXCEPT);
395 return !fetestexcept(FE_ALL_EXCEPT);
399 bool TrustingOp<int8_t>(int8_t & a, const int8_t & b, Optype op)
407 exact = (abs(sa) <= 127);
411 exact = (abs(sa) <= 127);
415 exact = (abs(sa) <= 127);
418 exact = (b != 0 && sa > b && sa % b == 0);