mirror of
https://github.com/Microsoft/calculator.git
synced 2025-08-14 02:26:50 -07:00
Simplify calculations of the nearest power of 2
Use compiler intrinsics to find the nearest power of 2 as quickly as possible. In addition, handle the 0 case, so that the program does not become stuck in an infinite loop if iNum is 0.
This commit is contained in:
parent
899014ee10
commit
dd8509fb3f
2 changed files with 10 additions and 25 deletions
|
@ -50,7 +50,7 @@ void CCalcEngine::SetRadixTypeAndNumWidth(RadixType radixtype, NUM_WIDTH numwidt
|
|||
DisplayNum();
|
||||
}
|
||||
|
||||
int32_t CCalcEngine::DwWordBitWidthFromNumWidth(NUM_WIDTH numwidth)
|
||||
uint32_t CCalcEngine::DwWordBitWidthFromNumWidth(NUM_WIDTH numwidth)
|
||||
{
|
||||
switch (numwidth)
|
||||
{
|
||||
|
@ -103,30 +103,15 @@ bool CCalcEngine::TryToggleBit(CalcEngine::Rational& rat, uint32_t wbitno)
|
|||
}
|
||||
|
||||
// Returns the nearest power of two
|
||||
int CCalcEngine::QuickLog2(int iNum)
|
||||
unsigned int CCalcEngine::QuickLog2(unsigned int iNum)
|
||||
{
|
||||
int iRes = 0;
|
||||
// Nearest power of 2 to 0 is 1
|
||||
if (!iNum)
|
||||
return 1;
|
||||
|
||||
// while first digit is a zero
|
||||
while (!(iNum & 1))
|
||||
{
|
||||
iRes++;
|
||||
iNum >>= 1;
|
||||
}
|
||||
|
||||
// if our number isn't a perfect square
|
||||
iNum = iNum >> 1;
|
||||
if (iNum)
|
||||
{
|
||||
// find the largest digit
|
||||
for (iNum = iNum >> 1; iNum; iNum = iNum >> 1)
|
||||
++iRes;
|
||||
|
||||
// and then add two
|
||||
iRes += 2;
|
||||
}
|
||||
|
||||
return iRes;
|
||||
// Count the number of leading 0's of iNum - 1,
|
||||
// and then shift 1 by that amount
|
||||
return 1U << (32 - __builtin_clz(iNum - 1));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -179,7 +179,7 @@ private:
|
|||
CalcEngine::Rational SciCalcFunctions(CalcEngine::Rational const& rat, uint32_t op);
|
||||
CalcEngine::Rational DoOperation(int operation, CalcEngine::Rational const& lhs, CalcEngine::Rational const& rhs);
|
||||
void SetRadixTypeAndNumWidth(RadixType radixtype, NUM_WIDTH numwidth);
|
||||
int32_t DwWordBitWidthFromNumWidth(NUM_WIDTH numwidth);
|
||||
uint32_t DwWordBitWidthFromNumWidth(NUM_WIDTH numwidth);
|
||||
uint32_t NRadixFromRadixType(RadixType radixtype);
|
||||
double GenerateRandomNumber();
|
||||
|
||||
|
@ -199,7 +199,7 @@ private:
|
|||
static std::vector<uint32_t> DigitGroupingStringToGroupingVector(std::wstring_view groupingString);
|
||||
std::wstring GroupDigits(std::wstring_view delimiter, std::vector<uint32_t> const& grouping, std::wstring_view displayString, bool isNumNegative = false);
|
||||
|
||||
static int QuickLog2(int iNum);
|
||||
static unsigned int QuickLog2(unsigned int iNum);
|
||||
static void ChangeBaseConstants(uint32_t radix, int maxIntDigits, int32_t precision);
|
||||
void BaseOrPrecisionChanged();
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue