Вывести экспоненциальную запись с одним начальным нулем с переполнением стека

Я генерирую текстовый файл для использования в качестве входного файла FORTRAN. Программа FORTRAN указывает, что значения, которые она читает, должны быть в таком формате, чтобы

1.0

должен быть напечатан как

0.1000000E+01

На данный момент самым близким, что я получил в использовании iostream, является

1.000000E+00

с кодом

cout << setprecision(6) << fixed << scientific << uppercase;
_set_output_format(_TWO_DIGIT_EXPONENT);
cout << 1.0 << endl;

Кто-нибудь знает лучший способ получить ведущий ноль, как показано выше, предпочтительно используя ostream вместо printf?

1

Решение

Как я уже сказал, то, что вы спрашиваете, нестандартно, но вы можете добиться этого с помощью хитрости:

#include <iostream>
#include <iomanip>
#include <cmath>

class Double {
public:
Double(double x): value(x) {}
const double value;
};

std::ostream & operator<< (std::ostream & stream, const Double & x) {
// So that the log does not scream
if (x.value == 0.) {
stream << 0.0;
return stream;
}

int exponent = floor(log10(std::abs(x.value)));
double base = x.value / pow(10, exponent);

// Transform here
base /= 10;
exponent += 1;

stream << base << 'E' << exponent; // Change the format as needed

return stream;
}

int main() {
// Use it like this
std::cout << std::setprecision(6) << std::fixed;
std::cout << Double(-2.203e-15) << std::endl;
return 0;
}

Double Обертка нужна, потому что вы не можете переопределить << за double,

Я не проверял этот способ разделения exponent а также base несмотря на шансы с плавающей точкой, может быть, вы можете придумать лучшую альтернативу, но вы поняли идею 🙂

1

Другие решения

С мыслью:

Не очень хороший ответ, потому что предпочтение отдается С ++.

char buf[20];
buf[0] = ' ';
double x = -1.234567;
sprintf(&buf[1], "% .6E", x*10);
if (buf[3] == '.') {  // detect if x was INF or NAN
buf[0] = buf[1];
buf[1] = '0';
buf[3] = buf[2];
buf[2] = '.';
}

// Cope with leading potential space if needed
if (buf[0] == ' ') memmove(&buf[0], &buf[1], strlen(buf));

printf("%s\n", buf);
// -0.1234567E+00

Слабость: проблема, если десятичной точкой не является «.» или х рядом с INF.

1

  1. Создайте фасет локали, который печатает без десятичной точки, и наполняйте его.
  2. cout << "0." << setprecision(6) << fixed << scientific << uppercase << number * 10;
0

printf ("%2.2f %+.0e %E \n", 2.016, 1.226, 0.1416);

выход: 2.02 + 1e + 000 1.416000E-001

-1
По вопросам рекламы [email protected]