mirror of
https://github.com/Microsoft/calculator.git
synced 2025-08-19 21:03:11 -07:00
Merge 630c354823
into be6eee0328
This commit is contained in:
commit
1c63b77b97
8 changed files with 91 additions and 96 deletions
|
@ -56,7 +56,7 @@ bool CalcInput::TryToggleSign(bool isIntegerMode, wstring_view maxNumStr)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CalcInput::TryAddDigit(unsigned int value, uint32_t radix, bool isIntegerMode, wstring_view maxNumStr, int32_t wordBitWidth, int maxDigits)
|
bool CalcInput::TryAddDigit(unsigned int value, uint32_t radix, bool isIntegerMode, wstring_view maxNumStr, uint32_t wordBitWidth, int maxDigits)
|
||||||
{
|
{
|
||||||
// Convert from an integer into a character
|
// Convert from an integer into a character
|
||||||
// This includes both normal digits and alpha 'digits' for radixes > 10
|
// This includes both normal digits and alpha 'digits' for radixes > 10
|
||||||
|
|
|
@ -21,10 +21,10 @@
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace CalcEngine;
|
using namespace CalcEngine;
|
||||||
using namespace CalcEngine::RationalMath;
|
using namespace RationalMath;
|
||||||
|
|
||||||
/* Routines for more complex mathematical functions/error checking. */
|
/* Routines for more complex mathematical functions/error checking. */
|
||||||
CalcEngine::Rational CCalcEngine::SciCalcFunctions(CalcEngine::Rational const& rat, uint32_t op)
|
Rational CCalcEngine::SciCalcFunctions(Rational const& rat, uint32_t op)
|
||||||
{
|
{
|
||||||
Rational result{};
|
Rational result{};
|
||||||
try
|
try
|
||||||
|
@ -39,7 +39,7 @@ CalcEngine::Rational CCalcEngine::SciCalcFunctions(CalcEngine::Rational const& r
|
||||||
case IDC_COM:
|
case IDC_COM:
|
||||||
if (m_radix == 10 && !m_fIntegerMode)
|
if (m_radix == 10 && !m_fIntegerMode)
|
||||||
{
|
{
|
||||||
result = -(RationalMath::Integer(rat) + 1);
|
result = -(Integer(rat) + 1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -78,7 +78,7 @@ CalcEngine::Rational CCalcEngine::SciCalcFunctions(CalcEngine::Rational const& r
|
||||||
result = Integer(rat);
|
result = Integer(rat);
|
||||||
|
|
||||||
uint64_t w64Bits = result.ToUInt64_t();
|
uint64_t w64Bits = result.ToUInt64_t();
|
||||||
uint64_t lsb = ((w64Bits & 0x01) == 1) ? 1 : 0;
|
uint64_t lsb = w64Bits & 0x01;
|
||||||
w64Bits >>= 1; // RShift by 1
|
w64Bits >>= 1; // RShift by 1
|
||||||
|
|
||||||
if (op == IDC_ROR)
|
if (op == IDC_ROR)
|
||||||
|
|
|
@ -50,7 +50,7 @@ void CCalcEngine::SetRadixTypeAndNumWidth(RadixType radixtype, NUM_WIDTH numwidt
|
||||||
DisplayNum();
|
DisplayNum();
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t CCalcEngine::DwWordBitWidthFromNumWidth(NUM_WIDTH numwidth)
|
uint32_t CCalcEngine::DwWordBitWidthFromNumWidth(NUM_WIDTH numwidth)
|
||||||
{
|
{
|
||||||
switch (numwidth)
|
switch (numwidth)
|
||||||
{
|
{
|
||||||
|
|
|
@ -151,7 +151,7 @@ private:
|
||||||
int m_nLastCom; // Last command entered.
|
int m_nLastCom; // Last command entered.
|
||||||
AngleType m_angletype; // Current Angle type when in dec mode. one of deg, rad or grad
|
AngleType m_angletype; // Current Angle type when in dec mode. one of deg, rad or grad
|
||||||
NUM_WIDTH m_numwidth; // one of qword, dword, word or byte mode.
|
NUM_WIDTH m_numwidth; // one of qword, dword, word or byte mode.
|
||||||
int32_t m_dwWordBitWidth; // # of bits in currently selected word size
|
uint32_t m_dwWordBitWidth; // # of bits in currently selected word size
|
||||||
|
|
||||||
std::unique_ptr<std::mt19937> m_randomGeneratorEngine;
|
std::unique_ptr<std::mt19937> m_randomGeneratorEngine;
|
||||||
std::unique_ptr<std::uniform_real_distribution<>> m_distr;
|
std::unique_ptr<std::uniform_real_distribution<>> m_distr;
|
||||||
|
@ -181,7 +181,7 @@ private:
|
||||||
CalcEngine::Rational SciCalcFunctions(CalcEngine::Rational const& rat, uint32_t op);
|
CalcEngine::Rational SciCalcFunctions(CalcEngine::Rational const& rat, uint32_t op);
|
||||||
CalcEngine::Rational DoOperation(int operation, CalcEngine::Rational const& lhs, CalcEngine::Rational const& rhs);
|
CalcEngine::Rational DoOperation(int operation, CalcEngine::Rational const& lhs, CalcEngine::Rational const& rhs);
|
||||||
void SetRadixTypeAndNumWidth(RadixType radixtype, NUM_WIDTH numwidth);
|
void SetRadixTypeAndNumWidth(RadixType radixtype, NUM_WIDTH numwidth);
|
||||||
int32_t DwWordBitWidthFromNumWidth(NUM_WIDTH numwidth);
|
uint32_t DwWordBitWidthFromNumWidth(NUM_WIDTH numwidth);
|
||||||
uint32_t NRadixFromRadixType(RadixType radixtype);
|
uint32_t NRadixFromRadixType(RadixType radixtype);
|
||||||
double GenerateRandomNumber();
|
double GenerateRandomNumber();
|
||||||
|
|
||||||
|
|
|
@ -60,7 +60,7 @@ namespace CalcEngine
|
||||||
|
|
||||||
void Clear();
|
void Clear();
|
||||||
bool TryToggleSign(bool isIntegerMode, std::wstring_view maxNumStr);
|
bool TryToggleSign(bool isIntegerMode, std::wstring_view maxNumStr);
|
||||||
bool TryAddDigit(unsigned int value, uint32_t radix, bool isIntegerMode, std::wstring_view maxNumStr, int32_t wordBitWidth, int maxDigits);
|
bool TryAddDigit(unsigned int value, uint32_t radix, bool isIntegerMode, std::wstring_view maxNumStr, uint32_t wordBitWidth, int maxDigits);
|
||||||
bool TryAddDecimalPt();
|
bool TryAddDecimalPt();
|
||||||
bool HasDecimalPt();
|
bool HasDecimalPt();
|
||||||
bool TryBeginExponent();
|
bool TryBeginExponent();
|
||||||
|
|
|
@ -290,13 +290,12 @@ void _divnumx(PNUMBER* pa, PNUMBER b, int32_t precision)
|
||||||
c->sign = a->sign * b->sign;
|
c->sign = a->sign * b->sign;
|
||||||
|
|
||||||
ptrc = c->mant + thismax;
|
ptrc = c->mant + thismax;
|
||||||
cdigits = 0;
|
|
||||||
|
|
||||||
DUPNUM(rem, a);
|
DUPNUM(rem, a);
|
||||||
rem->sign = b->sign;
|
rem->sign = b->sign;
|
||||||
rem->exp = b->cdigit + b->exp - rem->cdigit;
|
rem->exp = b->cdigit + b->exp - rem->cdigit;
|
||||||
|
|
||||||
while (cdigits++ < thismax && !zernum(rem))
|
for (cdigits = 0; cdigits < thismax && !zernum(rem); cdigits++)
|
||||||
{
|
{
|
||||||
int32_t digit = 0;
|
int32_t digit = 0;
|
||||||
*ptrc = 0;
|
*ptrc = 0;
|
||||||
|
@ -331,10 +330,10 @@ void _divnumx(PNUMBER* pa, PNUMBER b, int32_t precision)
|
||||||
rem->exp++;
|
rem->exp++;
|
||||||
ptrc--;
|
ptrc--;
|
||||||
}
|
}
|
||||||
cdigits--;
|
|
||||||
if (c->mant != ++ptrc)
|
if (c->mant != ++ptrc)
|
||||||
{
|
{
|
||||||
memmove(c->mant, ptrc, (int)(cdigits * sizeof(MANTTYPE)));
|
memmove(c->mant, ptrc, cdigits * sizeof(MANTTYPE));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!cdigits)
|
if (!cdigits)
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include "winerror_cross_platform.h"
|
#include "winerror_cross_platform.h"
|
||||||
#include <sstream>
|
|
||||||
#include <cstring> // for memmove, memcpy
|
#include <cstring> // for memmove, memcpy
|
||||||
#include "ratpak.h"
|
#include "ratpak.h"
|
||||||
|
|
||||||
|
@ -85,7 +84,7 @@ namespace
|
||||||
|
|
||||||
if (ullOperand <= UINT32_MAX)
|
if (ullOperand <= UINT32_MAX)
|
||||||
{
|
{
|
||||||
*pulResult = (uint32_t)ullOperand;
|
*pulResult = static_cast<uint32_t>(ullOperand);
|
||||||
hr = S_OK;
|
hr = S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,7 +129,7 @@ void* zmalloc(size_t a)
|
||||||
|
|
||||||
void _dupnum(_In_ PNUMBER dest, _In_ const NUMBER* const src)
|
void _dupnum(_In_ PNUMBER dest, _In_ const NUMBER* const src)
|
||||||
{
|
{
|
||||||
memcpy(dest, src, (int)(sizeof(NUMBER) + ((src)->cdigit) * (sizeof(MANTTYPE))));
|
memcpy(dest, src, sizeof(NUMBER) + src->cdigit * sizeof(MANTTYPE));
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -148,10 +147,12 @@ void _dupnum(_In_ PNUMBER dest, _In_ const NUMBER* const src)
|
||||||
void _destroynum(_Frees_ptr_opt_ PNUMBER pnum)
|
void _destroynum(_Frees_ptr_opt_ PNUMBER pnum)
|
||||||
|
|
||||||
{
|
{
|
||||||
if (pnum != nullptr)
|
if (pnum == nullptr)
|
||||||
{
|
{
|
||||||
free(pnum);
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free(pnum);
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -170,12 +171,13 @@ void _destroynum(_Frees_ptr_opt_ PNUMBER pnum)
|
||||||
void _destroyrat(_Frees_ptr_opt_ PRAT prat)
|
void _destroyrat(_Frees_ptr_opt_ PRAT prat)
|
||||||
|
|
||||||
{
|
{
|
||||||
if (prat != nullptr)
|
if (prat == nullptr)
|
||||||
{
|
{
|
||||||
destroynum(prat->pp);
|
return;
|
||||||
destroynum(prat->pq);
|
|
||||||
free(prat);
|
|
||||||
}
|
}
|
||||||
|
destroynum(prat->pp);
|
||||||
|
destroynum(prat->pq);
|
||||||
|
free(prat);
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -200,7 +202,7 @@ PNUMBER _createnum(_In_ uint32_t size)
|
||||||
if (SUCCEEDED(Calc_ULongAdd(size, 1, &cbAlloc)) && SUCCEEDED(Calc_ULongMult(cbAlloc, sizeof(MANTTYPE), &cbAlloc))
|
if (SUCCEEDED(Calc_ULongAdd(size, 1, &cbAlloc)) && SUCCEEDED(Calc_ULongMult(cbAlloc, sizeof(MANTTYPE), &cbAlloc))
|
||||||
&& SUCCEEDED(Calc_ULongAdd(cbAlloc, sizeof(NUMBER), &cbAlloc)))
|
&& SUCCEEDED(Calc_ULongAdd(cbAlloc, sizeof(NUMBER), &cbAlloc)))
|
||||||
{
|
{
|
||||||
pnumret = (PNUMBER)zmalloc(cbAlloc);
|
pnumret = static_cast<PNUMBER>(zmalloc(cbAlloc));
|
||||||
if (pnumret == nullptr)
|
if (pnumret == nullptr)
|
||||||
{
|
{
|
||||||
throw(CALC_E_OUTOFMEMORY);
|
throw(CALC_E_OUTOFMEMORY);
|
||||||
|
@ -227,12 +229,9 @@ PNUMBER _createnum(_In_ uint32_t size)
|
||||||
//
|
//
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
PRAT _createrat(void)
|
PRAT _createrat()
|
||||||
|
|
||||||
{
|
{
|
||||||
PRAT prat = nullptr;
|
PRAT prat = static_cast<PRAT>(zmalloc(sizeof(RAT)));
|
||||||
|
|
||||||
prat = (PRAT)zmalloc(sizeof(RAT));
|
|
||||||
|
|
||||||
if (prat == nullptr)
|
if (prat == nullptr)
|
||||||
{
|
{
|
||||||
|
@ -303,16 +302,16 @@ PRAT numtorat(_In_ PNUMBER pin, uint32_t radix)
|
||||||
PNUMBER nRadixxtonum(_In_ PNUMBER a, uint32_t radix, int32_t precision)
|
PNUMBER nRadixxtonum(_In_ PNUMBER a, uint32_t radix, int32_t precision)
|
||||||
|
|
||||||
{
|
{
|
||||||
PNUMBER sum = i32tonum(0, radix);
|
PNUMBER sum = Ui32tonum(0, radix);
|
||||||
PNUMBER powofnRadix = i32tonum(BASEX, radix);
|
PNUMBER powofnRadix = Ui32tonum(BASEX, radix);
|
||||||
|
|
||||||
// A large penalty is paid for conversion of digits no one will see anyway.
|
// A large penalty is paid for conversion of digits no one will see anyway.
|
||||||
// limit the digits to the minimum of the existing precision or the
|
// limit the digits to the minimum of the existing precision or the
|
||||||
// requested precision.
|
// requested precision.
|
||||||
uint32_t cdigits = precision + 1;
|
int32_t cdigits = precision + 1;
|
||||||
if (cdigits > (uint32_t)a->cdigit)
|
if (cdigits > a->cdigit)
|
||||||
{
|
{
|
||||||
cdigits = (uint32_t)a->cdigit;
|
cdigits = a->cdigit;
|
||||||
}
|
}
|
||||||
|
|
||||||
// scale by the internal base to the internal exponent offset of the LSD
|
// scale by the internal base to the internal exponent offset of the LSD
|
||||||
|
@ -322,7 +321,7 @@ PNUMBER nRadixxtonum(_In_ PNUMBER a, uint32_t radix, int32_t precision)
|
||||||
for (MANTTYPE* ptr = &(a->mant[a->cdigit - 1]); cdigits > 0; ptr--, cdigits--)
|
for (MANTTYPE* ptr = &(a->mant[a->cdigit - 1]); cdigits > 0; ptr--, cdigits--)
|
||||||
{
|
{
|
||||||
// Loop over all the bits from MSB to LSB
|
// Loop over all the bits from MSB to LSB
|
||||||
for (uint32_t bitmask = BASEX / 2; bitmask > 0; bitmask /= 2)
|
for (auto bitmask = BASEX >> 1; bitmask > 0; bitmask >>= 1)
|
||||||
{
|
{
|
||||||
addnum(&sum, sum, radix);
|
addnum(&sum, sum, radix);
|
||||||
if (*ptr & bitmask)
|
if (*ptr & bitmask)
|
||||||
|
@ -356,8 +355,8 @@ PNUMBER nRadixxtonum(_In_ PNUMBER a, uint32_t radix, int32_t precision)
|
||||||
|
|
||||||
PNUMBER numtonRadixx(_In_ PNUMBER a, uint32_t radix)
|
PNUMBER numtonRadixx(_In_ PNUMBER a, uint32_t radix)
|
||||||
{
|
{
|
||||||
PNUMBER pnumret = i32tonum(0, BASEX); // pnumret is the number in internal form.
|
PNUMBER pnumret = Ui32tonum(0, BASEX); // pnumret is the number in internal form.
|
||||||
PNUMBER num_radix = i32tonum(radix, BASEX);
|
PNUMBER num_radix = Ui32tonum(radix, BASEX);
|
||||||
MANTTYPE* ptrdigit = a->mant; // pointer to digit being worked on.
|
MANTTYPE* ptrdigit = a->mant; // pointer to digit being worked on.
|
||||||
|
|
||||||
// Digits are in reverse order, back over them LSD first.
|
// Digits are in reverse order, back over them LSD first.
|
||||||
|
@ -370,7 +369,7 @@ PNUMBER numtonRadixx(_In_ PNUMBER a, uint32_t radix)
|
||||||
// WARNING:
|
// WARNING:
|
||||||
// This should just smack in each digit into a 'special' thisdigit.
|
// This should just smack in each digit into a 'special' thisdigit.
|
||||||
// and not do the overhead of recreating the number type each time.
|
// and not do the overhead of recreating the number type each time.
|
||||||
thisdigit = i32tonum(*ptrdigit--, BASEX);
|
thisdigit = Ui32tonum(*ptrdigit--, BASEX);
|
||||||
addnum(&pnumret, thisdigit, BASEX);
|
addnum(&pnumret, thisdigit, BASEX);
|
||||||
destroynum(thisdigit);
|
destroynum(thisdigit);
|
||||||
}
|
}
|
||||||
|
@ -611,12 +610,12 @@ wchar_t NormalizeCharDigit(wchar_t c, uint32_t radix)
|
||||||
|
|
||||||
PNUMBER StringToNumber(wstring_view numberString, uint32_t radix, int32_t precision)
|
PNUMBER StringToNumber(wstring_view numberString, uint32_t radix, int32_t precision)
|
||||||
{
|
{
|
||||||
int32_t expSign = 1L; // expSign is exponent sign ( +/- 1 )
|
bool isNegative = false; // if number is negative
|
||||||
int32_t expValue = 0L; // expValue is exponent mantissa, should be unsigned
|
uint32_t expValue = 0; // expValue is exponent mantissa
|
||||||
|
|
||||||
PNUMBER pnumret = nullptr;
|
PNUMBER pnumret = nullptr;
|
||||||
createnum(pnumret, static_cast<uint32_t>(numberString.length()));
|
createnum(pnumret, static_cast<uint32_t>(numberString.length()));
|
||||||
pnumret->sign = 1L;
|
pnumret->sign = 1;
|
||||||
pnumret->cdigit = 0;
|
pnumret->cdigit = 0;
|
||||||
pnumret->exp = 0;
|
pnumret->exp = 0;
|
||||||
MANTTYPE* pmant = pnumret->mant + numberString.length() - 1;
|
MANTTYPE* pmant = pnumret->mant + numberString.length() - 1;
|
||||||
|
@ -641,8 +640,10 @@ PNUMBER StringToNumber(wstring_view numberString, uint32_t radix, int32_t precis
|
||||||
state = machine[state][ZR];
|
state = machine[state][ZR];
|
||||||
break;
|
break;
|
||||||
case L'^':
|
case L'^':
|
||||||
|
state = machine[state][EX];
|
||||||
|
break;
|
||||||
case L'e':
|
case L'e':
|
||||||
if (curChar == L'^' || radix == 10)
|
if (radix == 10)
|
||||||
{
|
{
|
||||||
state = machine[state][EX];
|
state = machine[state][EX];
|
||||||
break;
|
break;
|
||||||
|
@ -658,11 +659,13 @@ PNUMBER StringToNumber(wstring_view numberString, uint32_t radix, int32_t precis
|
||||||
switch (state)
|
switch (state)
|
||||||
{
|
{
|
||||||
case MANTS:
|
case MANTS:
|
||||||
pnumret->sign = (curChar == L'-') ? -1 : 1;
|
if ((curChar == L'-'))
|
||||||
|
pnumret->sign = -1;
|
||||||
break;
|
break;
|
||||||
case EXPSZ:
|
case EXPSZ:
|
||||||
case EXPS:
|
case EXPS:
|
||||||
expSign = (curChar == L'-') ? -1 : 1;
|
if ((curChar == L'-'))
|
||||||
|
isNegative = true;
|
||||||
break;
|
break;
|
||||||
case EXPDZ:
|
case EXPDZ:
|
||||||
case EXPD:
|
case EXPD:
|
||||||
|
@ -673,7 +676,7 @@ PNUMBER StringToNumber(wstring_view numberString, uint32_t radix, int32_t precis
|
||||||
if (pos != wstring_view::npos)
|
if (pos != wstring_view::npos)
|
||||||
{
|
{
|
||||||
expValue *= radix;
|
expValue *= radix;
|
||||||
expValue += static_cast<int32_t>(pos);
|
expValue += static_cast<uint32_t>(pos);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -725,7 +728,10 @@ PNUMBER StringToNumber(wstring_view numberString, uint32_t radix, int32_t precis
|
||||||
pnumret->exp--;
|
pnumret->exp--;
|
||||||
}
|
}
|
||||||
|
|
||||||
pnumret->exp += expSign * expValue;
|
if (isNegative)
|
||||||
|
pnumret->exp -= expValue;
|
||||||
|
else
|
||||||
|
pnumret->exp += expValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we don't have a number, clear our result.
|
// If we don't have a number, clear our result.
|
||||||
|
@ -824,7 +830,7 @@ PNUMBER i32tonum(int32_t ini32, uint32_t radix)
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
*pmant++ = (MANTTYPE)(ini32 % radix);
|
*pmant++ = static_cast<MANTTYPE>(ini32 % radix);
|
||||||
ini32 /= radix;
|
ini32 /= radix;
|
||||||
pnumret->cdigit++;
|
pnumret->cdigit++;
|
||||||
} while (ini32);
|
} while (ini32);
|
||||||
|
@ -859,7 +865,7 @@ PNUMBER Ui32tonum(uint32_t ini32, uint32_t radix)
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
*pmant++ = (MANTTYPE)(ini32 % radix);
|
*pmant++ = static_cast<MANTTYPE>(ini32 % radix);
|
||||||
ini32 /= radix;
|
ini32 /= radix;
|
||||||
pnumret->cdigit++;
|
pnumret->cdigit++;
|
||||||
} while (ini32);
|
} while (ini32);
|
||||||
|
@ -972,7 +978,7 @@ uint64_t rattoUi64(_In_ PRAT prat, uint32_t radix, int32_t precision)
|
||||||
destroyrat(prat32);
|
destroyrat(prat32);
|
||||||
destroyrat(pint);
|
destroyrat(pint);
|
||||||
|
|
||||||
return (((uint64_t)hi << 32) | lo);
|
return (static_cast<uint64_t>(hi) << 32) | lo;
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -992,17 +998,16 @@ int32_t numtoi32(_In_ PNUMBER pnum, uint32_t radix)
|
||||||
{
|
{
|
||||||
int32_t lret = 0;
|
int32_t lret = 0;
|
||||||
|
|
||||||
MANTTYPE* pmant = pnum->mant;
|
MANTTYPE* pmant = pnum->mant + pnum->cdigit - 1;
|
||||||
pmant += pnum->cdigit - 1;
|
|
||||||
|
|
||||||
int32_t expt = pnum->exp;
|
auto expt = pnum->exp;
|
||||||
for (int32_t length = pnum->cdigit; length > 0 && length + expt > 0; length--)
|
for (auto length = pnum->cdigit; length > 0 && length + expt > 0; length--)
|
||||||
{
|
{
|
||||||
lret *= radix;
|
lret *= radix;
|
||||||
lret += *(pmant--);
|
lret += *(pmant--);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (expt-- > 0)
|
for (; expt > 0; --expt)
|
||||||
{
|
{
|
||||||
lret *= radix;
|
lret *= radix;
|
||||||
}
|
}
|
||||||
|
@ -1025,37 +1030,34 @@ int32_t numtoi32(_In_ PNUMBER pnum, uint32_t radix)
|
||||||
|
|
||||||
bool stripzeroesnum(_Inout_ PNUMBER pnum, int32_t starting)
|
bool stripzeroesnum(_Inout_ PNUMBER pnum, int32_t starting)
|
||||||
{
|
{
|
||||||
bool fstrip = false;
|
|
||||||
// point pmant to the LeastCalculatedDigit
|
// point pmant to the LeastCalculatedDigit
|
||||||
MANTTYPE* pmant = pnum->mant;
|
MANTTYPE* pmant = pnum->mant;
|
||||||
int32_t cdigits = pnum->cdigit;
|
int32_t cdigits = pnum->cdigit;
|
||||||
// point pmant to the LSD
|
// point pmant to the LSD
|
||||||
if (cdigits > starting)
|
if (cdigits > starting)
|
||||||
{
|
{
|
||||||
pmant += cdigits - starting;
|
pmant = pmant + cdigits - starting;
|
||||||
cdigits = starting;
|
cdigits = starting;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check we haven't gone too far, and we are still looking at zeros.
|
// Check we haven't gone too far, and we are still looking at zeros.
|
||||||
while ((cdigits > 0) && !(*pmant))
|
if (cdigits < 1 || *pmant != 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
do
|
||||||
{
|
{
|
||||||
// move to next significant digit and keep track of digits we can
|
// move to next significant digit and keep track of digits we can
|
||||||
// ignore later.
|
// ignore later.
|
||||||
pmant++;
|
pmant++;
|
||||||
cdigits--;
|
cdigits--;
|
||||||
fstrip = true;
|
} while (cdigits > 0 && *pmant == 0);
|
||||||
}
|
|
||||||
|
|
||||||
// If there are zeros to remove.
|
// Remove the zeros
|
||||||
if (fstrip)
|
memmove(pnum->mant, pmant, cdigits * sizeof(MANTTYPE));
|
||||||
{
|
// And adjust exponent and digit count accordingly.
|
||||||
// Remove them.
|
pnum->exp += pnum->cdigit - cdigits;
|
||||||
memmove(pnum->mant, pmant, (int)(cdigits * sizeof(MANTTYPE)));
|
pnum->cdigit = cdigits;
|
||||||
// And adjust exponent and digit count accordingly.
|
return true;
|
||||||
pnum->exp += (pnum->cdigit - cdigits);
|
|
||||||
pnum->cdigit = cdigits;
|
|
||||||
}
|
|
||||||
return (fstrip);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -1099,7 +1101,7 @@ wstring NumberToString(_Inout_ PNUMBER& pnum, NumberFormat format, uint32_t radi
|
||||||
if (!zernum(pnum) && (pnum->cdigit >= precision || (length - exponent > precision && exponent >= -MAX_ZEROS_AFTER_DECIMAL)))
|
if (!zernum(pnum) && (pnum->cdigit >= precision || (length - exponent > precision && exponent >= -MAX_ZEROS_AFTER_DECIMAL)))
|
||||||
{
|
{
|
||||||
// Otherwise round.
|
// Otherwise round.
|
||||||
round = i32tonum(radix, radix);
|
round = Ui32tonum(radix, radix);
|
||||||
divnum(&round, num_two, radix, precision);
|
divnum(&round, num_two, radix, precision);
|
||||||
|
|
||||||
// Make round number exponent one below the LSD for the number.
|
// Make round number exponent one below the LSD for the number.
|
||||||
|
@ -1202,7 +1204,7 @@ wstring NumberToString(_Inout_ PNUMBER& pnum, NumberFormat format, uint32_t radi
|
||||||
result = L'-';
|
result = L'-';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (exponent <= 0 && !useSciForm)
|
if (exponent < 1 && !useSciForm)
|
||||||
{
|
{
|
||||||
result += L'0';
|
result += L'0';
|
||||||
result += g_decimalSeparator;
|
result += g_decimalSeparator;
|
||||||
|
@ -1217,26 +1219,24 @@ wstring NumberToString(_Inout_ PNUMBER& pnum, NumberFormat format, uint32_t radi
|
||||||
|
|
||||||
while (length > 0)
|
while (length > 0)
|
||||||
{
|
{
|
||||||
exponent--;
|
|
||||||
result += DIGITS[*pmant--];
|
result += DIGITS[*pmant--];
|
||||||
length--;
|
length--;
|
||||||
|
|
||||||
// Be more regular in using a decimal point.
|
// Be more regular in using a decimal point.
|
||||||
if (exponent == 0)
|
if (--exponent == 0)
|
||||||
{
|
{
|
||||||
result += g_decimalSeparator;
|
result += g_decimalSeparator;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while (exponent > 0)
|
if (exponent > 0)
|
||||||
{
|
{
|
||||||
result += L'0';
|
do
|
||||||
exponent--;
|
|
||||||
// Be more regular in using a decimal point.
|
|
||||||
if (exponent == 0)
|
|
||||||
{
|
{
|
||||||
result += g_decimalSeparator;
|
result += L'0';
|
||||||
}
|
} while (--exponent > 0);
|
||||||
|
// Be more regular in using a decimal point.
|
||||||
|
result += g_decimalSeparator;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (useSciForm)
|
if (useSciForm)
|
||||||
|
@ -1439,15 +1439,16 @@ PNUMBER i32prodnum(int32_t start, int32_t stop, uint32_t radix)
|
||||||
|
|
||||||
lret = i32tonum(1, radix);
|
lret = i32tonum(1, radix);
|
||||||
|
|
||||||
while (start <= stop)
|
for (; start <= stop; start++)
|
||||||
{
|
{
|
||||||
if (start)
|
if (!start)
|
||||||
{
|
{
|
||||||
tmp = i32tonum(start, radix);
|
continue;
|
||||||
mulnum(&lret, tmp, radix);
|
|
||||||
destroynum(tmp);
|
|
||||||
}
|
}
|
||||||
start++;
|
|
||||||
|
tmp = i32tonum(start, radix);
|
||||||
|
mulnum(&lret, tmp, radix);
|
||||||
|
destroynum(tmp);
|
||||||
}
|
}
|
||||||
return (lret);
|
return (lret);
|
||||||
}
|
}
|
||||||
|
@ -1470,7 +1471,7 @@ void numpowi32(_Inout_ PNUMBER* proot, int32_t power, uint32_t radix, int32_t pr
|
||||||
{
|
{
|
||||||
PNUMBER lret = i32tonum(1, radix);
|
PNUMBER lret = i32tonum(1, radix);
|
||||||
|
|
||||||
while (power > 0)
|
for (; power > 0; power >>= 1)
|
||||||
{
|
{
|
||||||
if (power & 1)
|
if (power & 1)
|
||||||
{
|
{
|
||||||
|
@ -1478,7 +1479,6 @@ void numpowi32(_Inout_ PNUMBER* proot, int32_t power, uint32_t radix, int32_t pr
|
||||||
}
|
}
|
||||||
mulnum(proot, *proot, radix);
|
mulnum(proot, *proot, radix);
|
||||||
TRIMNUM(*proot, precision);
|
TRIMNUM(*proot, precision);
|
||||||
power >>= 1;
|
|
||||||
}
|
}
|
||||||
destroynum(*proot);
|
destroynum(*proot);
|
||||||
*proot = lret;
|
*proot = lret;
|
||||||
|
@ -1511,9 +1511,7 @@ void ratpowi32(_Inout_ PRAT* proot, int32_t power, int32_t precision)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PRAT lret = nullptr;
|
PRAT lret = i32torat(1);
|
||||||
|
|
||||||
lret = i32torat(1);
|
|
||||||
|
|
||||||
while (power > 0)
|
while (power > 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -419,8 +419,8 @@ void _divnum(PNUMBER* pa, PNUMBER b, uint32_t radix, int32_t precision)
|
||||||
destroynum(tmp);
|
destroynum(tmp);
|
||||||
|
|
||||||
int32_t digit;
|
int32_t digit;
|
||||||
int32_t cdigits = 0;
|
int32_t cdigits;
|
||||||
while (cdigits++ < thismax && !zernum(rem))
|
for (cdigits = 0; cdigits < thismax && !zernum(rem); cdigits++)
|
||||||
{
|
{
|
||||||
digit = radix - 1;
|
digit = radix - 1;
|
||||||
PNUMBER multiple = nullptr;
|
PNUMBER multiple = nullptr;
|
||||||
|
@ -442,11 +442,10 @@ void _divnum(PNUMBER* pa, PNUMBER b, uint32_t radix, int32_t precision)
|
||||||
rem->exp++;
|
rem->exp++;
|
||||||
*ptrc-- = (MANTTYPE)digit;
|
*ptrc-- = (MANTTYPE)digit;
|
||||||
}
|
}
|
||||||
cdigits--;
|
|
||||||
|
|
||||||
if (c->mant != ++ptrc)
|
if (c->mant != ++ptrc)
|
||||||
{
|
{
|
||||||
memmove(c->mant, ptrc, (int)(cdigits * sizeof(MANTTYPE)));
|
memmove(c->mant, ptrc, cdigits * sizeof(MANTTYPE));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cleanup table structure
|
// Cleanup table structure
|
||||||
|
@ -604,12 +603,11 @@ bool zernum(_In_ PNUMBER a)
|
||||||
{
|
{
|
||||||
int32_t length;
|
int32_t length;
|
||||||
MANTTYPE* pcha;
|
MANTTYPE* pcha;
|
||||||
length = a->cdigit;
|
|
||||||
pcha = a->mant;
|
pcha = a->mant;
|
||||||
|
|
||||||
// loop over all the digits until you find a nonzero or until you run
|
// loop over all the digits until you find a nonzero or until you run
|
||||||
// out of digits
|
// out of digits
|
||||||
while (length-- > 0)
|
for (length = a->cdigit; length > 0; length--)
|
||||||
{
|
{
|
||||||
if (*pcha++)
|
if (*pcha++)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue