Форматируем по-фортрановски
Обмен данными со старыми системами, например, с АСТРА, накладывает дополнительные ограничения на способ записи файлов. Так, обменный формат может регламентировать, что вещественному числу в файле отведено не более, чем 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.