amath  1.8.5
Simple command line calculator
DecimalSystem Class Reference

#include <ntextd.h>

Inheritance diagram for DecimalSystem:
Collaboration diagram for DecimalSystem:

Public Member Functions

 DecimalSystem ()
 
 DecimalSystem (unsigned int digits)
 
 DecimalSystem (unsigned int digits, const char fractionPoint)
 
 ~DecimalSystem ()
 
virtual const char * GetText (Number *number)
 
- Public Member Functions inherited from PositionalNumeralSystem
 PositionalNumeralSystem (unsigned int base, unsigned int digits, const char fractionPoint)
 
 ~PositionalNumeralSystem ()
 
virtual const char * GetName ()
 
virtual const char * GetPrefix ()
 
virtual unsigned int GetDigits ()
 
virtual void SetDigits (unsigned int digits)
 
virtual const char GetFractionPoint ()
 
virtual void SetFractionPoint (const char fractionPoint)
 
virtual NumberParse (const char *text, unsigned int *length, char **end)
 
- Public Member Functions inherited from NumeralSystem
 NumeralSystem ()
 
virtual ~NumeralSystem ()
 
virtual NumberParse (const char *text)
 

Private Member Functions

const char * GetText (double number) const
 

Additional Inherited Members

- Protected Member Functions inherited from PositionalNumeralSystem
const char * GetSpecialCase (Number *number)
 
void IntegerToBuffer (double value, unsigned int digits, int *outdigits) const
 
- Protected Attributes inherited from PositionalNumeralSystem
double baseDouble
 
unsigned int digits
 
char fractionPoint
 
- Protected Attributes inherited from NumeralSystem
CharBufferbuf
 

Detailed Description

Definition at line 35 of file ntextd.h.

Constructor & Destructor Documentation

◆ DecimalSystem() [1/3]

DecimalSystem::DecimalSystem ( )

Definition at line 62 of file ntextd.cpp.

References PositionalNumeralSystem::PositionalNumeralSystem().

62  : PositionalNumeralSystem(10, 5, '\0')
63 {
64 }
PositionalNumeralSystem(unsigned int base, unsigned int digits, const char fractionPoint)
Definition: ntextp.cpp:40
Here is the call graph for this function:

◆ DecimalSystem() [2/3]

DecimalSystem::DecimalSystem ( unsigned int  digits)

Definition at line 66 of file ntextd.cpp.

References PositionalNumeralSystem::PositionalNumeralSystem().

Referenced by PlotStatement::Execute(), MemoryStatement::Execute(), DigitsStatement::Execute(), PreferencesBase::GetDescription(), PositionalNumeralSystem::GetName(), Parser::ParseDigistStatement(), and Parser::ParseNumeralStatement().

66  :
68 {
69 }
unsigned int digits
Definition: ntextp.h:61
PositionalNumeralSystem(unsigned int base, unsigned int digits, const char fractionPoint)
Definition: ntextp.cpp:40
Here is the call graph for this function:
Here is the caller graph for this function:

◆ DecimalSystem() [3/3]

DecimalSystem::DecimalSystem ( unsigned int  digits,
const char  fractionPoint 
)

Definition at line 71 of file ntextd.cpp.

References PositionalNumeralSystem::PositionalNumeralSystem().

Referenced by Program::NewPositionalInput(), Program::NewPositionalOutput(), and Program::Program().

71  :
73 {
74 }
unsigned int digits
Definition: ntextp.h:61
PositionalNumeralSystem(unsigned int base, unsigned int digits, const char fractionPoint)
Definition: ntextp.cpp:40
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ~DecimalSystem()

DecimalSystem::~DecimalSystem ( )

Definition at line 76 of file ntextd.cpp.

77 {
78 }

Member Function Documentation

◆ GetText() [1/2]

const char * DecimalSystem::GetText ( Number number)
virtual

Reimplemented from PositionalNumeralSystem.

Definition at line 80 of file ntextd.cpp.

References CharBuffer::Append(), NumeralSystem::buf, cimag(), creal(), CharBuffer::Empty(), ComplexNumber::GetComplexValue(), Number::GetRealValue(), PositionalNumeralSystem::GetSpecialCase(), CharBuffer::GetString(), GetText(), nsysreal, and Number::system.

81 {
82  const char *sc = GetSpecialCase(number);
83  if (sc != nullptr)
84  {
85  return sc;
86  }
87 
88  if (number->system == nsysreal)
89  {
90  buf->Empty();
91  return GetText(number->GetRealValue());
92  }
93 
94  complex w = ((ComplexNumber *)number)->GetComplexValue();
95  double a = creal(w);
96  double b = cimag(w);
97 
98  buf->Empty();
99  if (a != 0.0)
100  {
101  GetText(a);
102  }
103 
104  if (a != 0.0 && b > 0.0)
105  {
106  buf->Append('+');
107  }
108 
109  if (b != 0.0)
110  {
111  GetText(b);
112  buf->Append('i');
113  }
114 
115  return buf->GetString();
116 }
CharBuffer * buf
Definition: ntext.h:65
Definition: mathi.h:48
void Empty()
Definition: charbuf.cpp:218
double cimag(complex z)
Imaginary part of complex number.
Definition: prim.c:46
char * GetString() const
Definition: charbuf.cpp:306
NumberSystem system
Definition: numb.h:171
void Append(const char *source)
Definition: charbuf.cpp:262
const char * GetSpecialCase(Number *number)
Definition: ntextp.cpp:117
double creal(complex z)
Real part of complex number.
Definition: prim.c:38
virtual double GetRealValue()=0
Represent a complex number with 2 components of 15 significant digits.
Definition: cplex.h:46
virtual const char * GetText(Number *number)
Definition: ntextd.cpp:80
Definition: numb.h:61
Here is the call graph for this function:

◆ GetText() [2/2]

const char * DecimalSystem::GetText ( double  number) const
private

Definition at line 118 of file ntextd.cpp.

References CharBuffer::Append(), NumeralSystem::buf, CharBuffer::Contains(), CutoffMode_FractionLength, CutoffMode_TotalLength, PositionalNumeralSystem::digits, Dragon4(), CharBuffer::EnsureGrowth(), fabs(), FloatUnion64::floatingPoint, PositionalNumeralSystem::fractionPoint, FloatUnion64::GetExponent(), FloatUnion64::GetMantissa(), CharBuffer::GetString(), PositionalNumeralSystem::IntegerToBuffer(), FloatUnion64::IsNegative(), log10(), log2i(), MemCopy(), CharBuffer::RemoveTrailing(), and trunc().

Referenced by GetText().

119 {
120  int32_t printExponent = 0;
121  double dexponent = log10(fabs(number));
122  int32_t precision = digits - (int32_t)trunc(dexponent) - 1;
123  int32_t lim = 15;
124  bool sci = (dexponent > 9.0 || dexponent < -8.0);
125  if (sci)
126  {
127  precision = digits;
128  }
129  else if (dexponent < 0.0)
130  {
131  precision++;
132  lim--;
133  }
134 
135  if (precision > lim)
136  {
137  precision = lim;
138  }
139 
140  static const int size = 64;
141  char *out = new char[size];
142  char *pOutBuffer = out;
143  uint32_t bufferSize = size;
144 
145  FloatUnion64 floatUnion;
146  floatUnion.floatingPoint = number;
147  uint32_t floatExponent = floatUnion.GetExponent();
148  uint64_t floatMantissa = floatUnion.GetMantissa();
149 
150  if (floatUnion.IsNegative())
151  {
152  pOutBuffer[0] = '-';
153  ++pOutBuffer;
154  --bufferSize;
155  }
156 
157  uint64_t mantissa;
158  int32_t exponent;
159  uint32_t mantissaHighBitIdx;
160  bool hasUnequalMargins;
161 
162  if (floatExponent != 0)
163  {
164  // normal
165  mantissa = (1ull << 52) | floatMantissa;
166  exponent = floatExponent - 1023 - 52;
167  mantissaHighBitIdx = 52;
168  hasUnequalMargins = (floatExponent != 1) && (floatMantissa == 0);
169  }
170  else
171  {
172  // subnormal
173  mantissa = floatMantissa;
174  exponent = 1 - 1023 - 52;
175  mantissaHighBitIdx = log2i(mantissa);
176  hasUnequalMargins = false;
177  }
178 
179  if (!sci)
180  {
181  int32_t printExponent;
182  uint32_t numPrintDigits;
183  uint32_t maxPrintLen = bufferSize - 1;
184  numPrintDigits = Dragon4(mantissa,
185  exponent,
186  mantissaHighBitIdx,
187  hasUnequalMargins,
189  precision,
190  pOutBuffer,
191  maxPrintLen,
192  &printExponent);
193 
194  // track the number of digits past the decimal point that have been printed
195  uint32_t numFractionDigits = 0;
196 
197  // if output has a whole number
198  if (printExponent >= 0)
199  {
200  // leave the whole number at the start of the buffer
201  uint32_t numWholeDigits = printExponent + 1;
202  if (numPrintDigits < numWholeDigits)
203  {
204  // don't overflow the buffer
205  if (numWholeDigits > maxPrintLen)
206  numWholeDigits = maxPrintLen;
207 
208  // add trailing zeros up to the decimal point
209  for (; numPrintDigits < numWholeDigits; ++numPrintDigits)
210  pOutBuffer[numPrintDigits] = '0';
211  }
212  // insert the decimal point prior to the fraction
213  else if (numPrintDigits > (uint32_t)numWholeDigits)
214  {
215  numFractionDigits = numPrintDigits - numWholeDigits;
216  uint32_t maxFractionDigits = maxPrintLen - numWholeDigits - 1;
217  if (numFractionDigits > maxFractionDigits)
218  numFractionDigits = maxFractionDigits;
219 
220  MemCopy(pOutBuffer + numWholeDigits + 1, pOutBuffer + numWholeDigits, numFractionDigits);
221  pOutBuffer[numWholeDigits] = fractionPoint;
222  numPrintDigits = numWholeDigits + 1 + numFractionDigits;
223  }
224  }
225  else
226  {
227  // shift out the fraction to make room for the leading zeros
228  if (maxPrintLen > 2)
229  {
230  uint32_t numFractionZeros = (uint32_t)-printExponent - 1;
231  uint32_t maxFractionZeros = maxPrintLen - 2;
232  if (numFractionZeros > maxFractionZeros)
233  numFractionZeros = maxFractionZeros;
234 
235  uint32_t digitsStartIdx = 2 + numFractionZeros;
236 
237  // shift the significant digits right such that there is room for leading zeros
238  numFractionDigits = numPrintDigits;
239  uint32_t maxFractionDigits = maxPrintLen - digitsStartIdx;
240  if (numFractionDigits > maxFractionDigits)
241  numFractionDigits = maxFractionDigits;
242 
243  MemCopy(pOutBuffer + digitsStartIdx, pOutBuffer, numFractionDigits);
244 
245  // insert the leading zeros
246  for (uint32_t i = 2; i < digitsStartIdx; ++i)
247  pOutBuffer[i] = '0';
248 
249  // update the counts
250  numFractionDigits += numFractionZeros;
251  numPrintDigits = numFractionDigits;
252  }
253 
254  // add the decimal point
255  if (maxPrintLen > 1)
256  {
257  pOutBuffer[1] = fractionPoint;
258  numPrintDigits += 1;
259  }
260 
261  // add the initial zero
262  if (maxPrintLen > 0)
263  {
264  pOutBuffer[0] = '0';
265  numPrintDigits += 1;
266  }
267  }
268 
269  // add trailing zeros up to precision length
270  if (precision > (int32_t)numFractionDigits && numPrintDigits < maxPrintLen)
271  {
272  // add a decimal point if this is the first fractional digit we are printing
273  if (numFractionDigits == 0)
274  {
275  pOutBuffer[numPrintDigits++] = fractionPoint;
276  }
277 
278  // compute the number of trailing zeros needed
279  uint32_t totalDigits = numPrintDigits + (precision - numFractionDigits);
280  if (totalDigits > maxPrintLen)
281  totalDigits = maxPrintLen;
282 
283  for (; numPrintDigits < totalDigits; ++numPrintDigits)
284  pOutBuffer[numPrintDigits] = '0';
285  }
286 
287  pOutBuffer[numPrintDigits] = '\0';
288  }
289  else
290  {
291  uint32_t numPrintDigits;
292  numPrintDigits = Dragon4(mantissa,
293  exponent,
294  mantissaHighBitIdx,
295  hasUnequalMargins,
297  precision + 1,
298  pOutBuffer,
299  bufferSize,
300  &printExponent);
301 
302  char *pCurOut = pOutBuffer;
303  pCurOut += 1;
304 
305  // insert the decimal point prior to the fractional number
306  uint32_t numFractionDigits = numPrintDigits - 1;
307  if (numFractionDigits > 0 && bufferSize > 1)
308  {
309  uint32_t maxFractionDigits = bufferSize - 2;
310  if (numFractionDigits > maxFractionDigits)
311  numFractionDigits = maxFractionDigits;
312 
313  MemCopy(pCurOut + 1, pCurOut, numFractionDigits);
314  pCurOut[0] = fractionPoint;
315  pCurOut += (1 + numFractionDigits);
316  }
317 
318  pCurOut[0] = '\0';
319  }
320 
321  buf->EnsureGrowth(size);
322  buf->Append(out);
323 
324  if (fractionPoint != '\0' && buf->Contains(fractionPoint))
325  {
326  while (buf->RemoveTrailing('0'))
327  ;
329  }
330 
331  if (printExponent != 0)
332  {
333  buf->Append('e');
334  if (printExponent >= 0)
335  {
336  buf->Append('+');
337  }
338  else
339  {
340  buf->Append('-');
341  printExponent = -printExponent;
342  }
343  int temp;
344  IntegerToBuffer(printExponent, 3, &temp);
345  }
346 
347  if (fractionPoint != '\0' && buf->Contains(fractionPoint) && !buf->Contains('e'))
348  {
349  while (buf->RemoveTrailing('0'))
350  ;
352  }
353 
354  delete[] out;
355  return buf->GetString();
356 }
CharBuffer * buf
Definition: ntext.h:65
unsigned int digits
Definition: ntextp.h:61
double log10(double x)
Base 10 logarithm function.
Definition: log10.c:93
char * GetString() const
Definition: charbuf.cpp:306
void IntegerToBuffer(double value, unsigned int digits, int *outdigits) const
Definition: ntextp.cpp:316
bool RemoveTrailing(const char c)
Definition: charbuf.cpp:270
int32_t GetExponent() const
Definition: numb.h:51
void Append(const char *source)
Definition: charbuf.cpp:262
bool IsNegative() const
Definition: numb.h:45
double floatingPoint
Definition: numb.h:53
unsigned int log2i(unsigned int x)
uint64_t GetMantissa() const
Definition: numb.h:52
void MemCopy(void *destination, const void *source, unsigned int length)
Copy a block of memory, handling overlap.
Definition: memcpy.c:75
void EnsureGrowth(unsigned int size)
Definition: charbuf.cpp:169
uint32_t Dragon4(const uint64_t mantissa, const int32_t exponent, const uint32_t mantissaHighBitIdx, const bool hasUnequalMargins, const tCutoffMode cutoffMode, uint32_t cutoffNumber, char *pOubooluffer, uint32_t bufferSize, int32_t *pOutExponent)
Definition: bigint.cpp:608
bool Contains(const char c) const
Definition: charbuf.cpp:199
double fabs(double x)
Returns the absolute value of x.
Definition: fabs.c:51
double trunc(double x)
Truncate function.
Definition: trunc.c:52
Here is the call graph for this function:
Here is the caller graph for this function:

The documentation for this class was generated from the following files: