Получается такая штука:
В одном месте программы есть double, который "чуть меньше" 10. После возврата его из функции и передаче в другую функцию, там оказывается double, который "чуть больше" 10. Эффект проявляется в релизном билде MinGW 4.4.0 (-O2) и не повторяется на MSVC (дебаг/релиз). Эффект исчезает, если вставить побольше дебажного вывода...
Код:
struct TNormalizeDouble
{
double stagnat;
int_fast16_t exp;
};
TNormalizeDouble normalizeDouble(double val)
{
TNormalizeDouble res = {val, 0};
if (res.stagnat < 0) // неверный вход - уходим
return res;
/* Использован код из стандартной библиотеки IAR (frmwri.c) */
if (res.stagnat >= 1)
{
while (res.stagnat >= 1e11) /* To speed up things a bit */
{
res.stagnat /= 1e10;
res.exp += 10;
}
while (res.stagnat >= 10)
{
res.stagnat /= 10;
res.exp++;
}
}
else if (res.stagnat) /* Not just 0.0 */
{
while (res.stagnat <= 1e-10) /* To speed up things a bit */
{
//******* std::cout << "1e10 \n";
res.stagnat *= 1e10;
res.exp -= 10;
}
while (res.stagnat < 1)
{
//******* std::cout << "10 \n";
res.stagnat *= 10;
res.exp--;
}
}
std::cout << res.stagnat << ' ' << (int)res.stagnat << ' ' << (res.stagnat < 10) << '\n';
return res;
}
bool NormDoubleToBCD(TBCDLocation bcd, double value, uint_fast8_t bcdDigCnt)
{
std::cout << value << ' ' << (int)value << ' ' << (value < 10) << '\n';
...
}
void someFunc(double value)
{
// тут код, который не трогает value
TNormalizeDouble nd = normalizeDouble(value);
// тут код, который не трогает nd
NormDoubleToBCD(bcd, nd.stagnat, bcdDigCnt);
}
При вызове someFunc(1e-20) получаю:
10 9
1
10 10 0
Если раскомментить помеченные ******* строки, то эффект пропадет