MinGW 4.4: Странности с double
От: enji  
Дата: 25.07.10 07:38
Оценка:
Получается такая штука:
В одном месте программы есть 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


Если раскомментить помеченные ******* строки, то эффект пропадет
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.