const fix16_t fix16_minimum = 0x80000000; /*!< the minimum value of fix16_t */ const fix16_t fix16_overflow = 0x80000000; /*!< the value used to indicate overflows */
staticinline uint32_t fix_abs(fix16_t in)
{ if (in == fix16_minimum)
{ // minimum negative number has same representation as // its absolute value in unsigned return0x80000000;
} else
{ return (in >= 0) ? in : -in;
}
}
/* 64-bit implementation for fix16_mul. Fastest version for e.g. ARM Cortex M3. *Performsa32*32->64bitmultiplication.Themiddle32bitsaretheresult, *bottom16bitsareusedforrounding,andupper16bitsareusedforoverflow *detection.
*/
/* 32-bit implementation of fix16_div. Fastest version for e.g. ARM Cortex M3. *Performs32-bitdivisionsrepeatedlytoreducetheremainder.Forthisto *beefficient,theprocessorhastohave32-bithardwaredivision.
*/
fix16_t fix16_div(fix16_t a, fix16_t b)
{ // This uses a hardware 32/32 bit division multiple times, until we have // computed all the bits in (a<<17)/b. Usually this takes 1-3 iterations.
// Kick-start the division a bit. // This improves speed in the worst-case scenarios where N and D are large // It gets a lower estimate for the result by N/(D >> 17 + 1). if (divider & 0xFFF00000)
{
uint32_t shifted_div = (divider >> 17) + 1;
quotient = remainder / shifted_div;
uint64_t tmp = (quotient * static_cast<uint64_t>(divider)) >> 17;
remainder -= static_cast<uint32_t>(tmp);
}
// If the divider is divisible by 2^n, take advantage of it. while (!(divider & 0xF) && bit_pos >= 4)
{
divider >>= 4;
bit_pos -= 4;
}
while (remainder > 0 && bit_pos >= 0)
{ // Shift remainder as much as we can without overflowing int shift = std::countl_zero(remainder); if (shift > bit_pos)
shift = bit_pos; if (shift)
{
remainder = (remainder & mask(32 - shift)) << shift;
bit_pos -= shift;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.