Manifold Geometry // Многообразная Геометрия

Форматируем по-фортрановски

/ Просмотров: 383

Обмен данными со старыми системами, например, с АСТРА, накладывает дополнительные ограничения на способ записи файлов. Так, обменный формат может регламентировать, что вещественному числу в файле отведено не более, чем N символов, причем исключительно в экспонентной форме. Все эти милые тонкости делают невозможным «просто записать файл» средствами C++ — такой файл попросту не прочитается в целевой системе.

Ошибка формата данных в АСТРА.

Удивительно, но добиться совместимости вывода C++ и Фортран не так уж просто, даже с использованием специальных функций. Приведу пару примеров искомого преобразования числа. Для положительных чисел:

31.415926535 -> 0.3141593E+02

Для отрицательных:

-31.415926535 -> -.3141593E+02

Тонкость в том, что форматированный вывод должен занимать 13 символов, независимо от знака и значения. В отрицательном числе знак "-" требует дополнительного места, которое в «фортранном» выводе отнимается у нуля (мантисса пустая). Для преодоления этой трудности мы реализовали собственную примитивную функцию форматирования, листинг которой привожу здесь:

void fixprint(char *s, const int len)
{
  if ( s[0] == '-' )
  {
    for ( int j = 2; j < len; ++j  )
      s[j-1] = s[j];
    
    s[len-1] = '\0'; // Zero-trailing.
  }
}
  
char* format_fortran_float(char*    result,
                           unsigned width,
                           double   number)
{
  int exponent = 0;
  for (; fabs(number) > 1.0; exponent++) number /= 10;
  
  sprintf( result, "%.*fE%+03d", 7, number, exponent );
  
  fixprint(result, width);
  
  return result;
}
  
char* fortranize(const double val,
                 char*        buff)
{
  return format_fortran_float(buff, FORTRAN_BUFSIZE, val);
}

Функция fortranize использует стандартный вызов sprintf для перевода числа в экспонентную форму. Затем выполняется простейшая операция посимвольного сдвига fixprint, позволяющая избавиться от нуля в мантиссе, если число отрицательно.

Want to discuss this? Jump in to our forum.