3

I am using this code to output a scientific notation number to a file:

file << scientific << setprecision(10) << num << endl;

For example, if the number is 3.0, I get 3.0000000000E+00 from the code. How do I make the digits of the exponent part to be 3 digits? I want to get 3.0000000000E+000.

  • Which compiler are you using? I believe the standard of `gcc` should be with three digits. – darclander Jun 14 '20 at 18:33
  • I'm using visual studio. Compiler version is Microsoft (R) C/C++ Optimizing Compiler Version 19.25.28614 for x86 – user3.141592653 Jun 14 '20 at 18:39
  • Related: https://stackoverflow.com/questions/31331723/how-to-control-the-number-of-exponent-digits-after-e-in-c-printf-e (if not a dupe). Also: https://stackoverflow.com/questions/9226400/portable-printing-of-exponent-of-a-double-to-c-iostreams . In short, you can't, you have to "manually" modify the output. – Bob__ Jun 14 '20 at 19:09
  • @Bob__ are you sure about that? According to [These docs](http://www.cplusplus.com/reference/ios/scientific/), the output has 3 digit exponents? – darclander Jun 14 '20 at 19:17
  • @darclander See e.g. https://stackoverflow.com/a/50620148/4944425 where it quotes the C11 standard *"The exponent always contains at least two digits, and only as many more digits as necessary to represent the exponent. If the value is zero, the exponent is zero"*. Also: https://stackoverflow.com/a/35738440/4944425 – Bob__ Jun 14 '20 at 19:28
  • Does this answer your question? [How to make C++ cout not use scientific notation](https://stackoverflow.com/questions/5212018/how-to-make-c-cout-not-use-scientific-notation) –  Jun 14 '20 at 20:30
  • @Bob__ Note that the question is currently tagged C++, not C. So I'm not sure the C11 standard applies here. –  Jun 14 '20 at 20:41
  • @Chipster Well, I haven't found a direct quote of the standard, but my interpretation of how [this function](https://en.cppreference.com/w/cpp/locale/num_put/put) (which *"is called by all formatted output stream operators, such as std::cout << n;"*) behaves: *" If the type of v is a floating-point type, the the first applicable choice of the following is selected: ... If `floatfield == std::ios_base::scientific && !uppercase`, will use conversion specifier `%e`"*, I belive refers to the [std::printf](https://en.cppreference.com/w/cpp/io/c/fprintf) format specifier. – Bob__ Jun 14 '20 at 21:21

1 Answers1

1

It seems like as @Bob__ stated that visual studio used to have a function called: _set_output_format which allowed you to change the exponent BUT this was removed in the Visual Studio 2015 version I believe.

As quoted in Portable printing of exponent of a double to C++ iostreams.

The %e and %E format specifiers format a floating point number as a decimal mantissa and exponent. The %g and %G format specifiers also format numbers in this form in some cases. In previous versions, the CRT would always generate strings with three-digit exponents. For example, printf("%e\n", 1.0)would print 1.000000e+000. This was incorrect: C requires that if the exponent is representable using only one or two digits, then only two digits are to be printed.

In Visual Studio 2005 a global conformance switch was added: _set_output_format. A program could call this function with the argument _TWO_DIGIT_EXPONENT, to enable conforming exponent printing. The default behavior has been changed to the standards-conforming exponent printing mode.

So in order to resolve your issue if you really want to write with a 3 digit exponent would be to modify the output. You can do so by transforming the double into a string, example:

#include <iostream>
#include <string>
#include <sstream>
#include <iomanip>


std::string getStrCpy(double dbl) {
    std::ostringstream str;
    str << std::scientific << std::setprecision(10) << dbl;
    std::string s = str.str();
    std::cout << s; // Prints 3.0000000000e+00
    return s;
}

int main() {

    double d = 3.0;
    std::cout.precision(10);
    std::cout << std::scientific;

    std::cout << d << '\n'; // Prints 3.0000000000e+00
    getStrCpy(d); // Will also print 3.0000000000e+00

    return 0;
}

Now getStrCpy() will return a string of the double you were trying to print which you can modify in order to add an extra number to your exponent.

darclander
  • 1,526
  • 1
  • 13
  • 35