wstringstream default format flag - c++

I am trying to convert 3 byte double to string. Following is my code.
double b = 0xFFFFFF;
std::wstring ss;
std::wstringstream sOut;
sOut << b;
ss = boost::lexical_cast<std::wstring>(sOut.str());
I expect output to be 16777215. But "ss" has the value 1.67772e+007.
However when I use "fixed" flag, I get the expected output.
sOut << std::fixed
My question is whether wstringstream has "scientific" flag by default ?
Thanks,

All streams (not just wstringstream) have floating-point formatting flags set to ios_base::defaultfloat by default, which requests the formatting you're observing, which is equivalent to printf's conversion specifier %g.
To quote C's description of %g
A double argument representing a floating-point number is converted in style f or e (or in style F or E in the case of a G conversion specifier), depending on the value converted and the precision. Let P equal the precision if nonzero, 6 if the precision is omitted, or 1 if the precision is zero. Then, if a conversion with style E would have an exponent of X:
if P > X >= -4, the conversion is with style f (or F) and precision P - (X + 1).
otherwise, the conversion is with style e (or E) and precision P - 1.
In your case, "the style e" is selected.

Related

Unexpected results using sprintf and %g to convert double to string

When I use MBCS and msvcr120.dll (12.0.40660.0) I get unexpected results when using %g with sprintf to convert a double to a string. The documentation for %g says default precision will be 6. Why am I seeing the results below?
{
double d = 1234567.00;
char buf[100];
sprintf_s(buf, sizeof(buf), "%g", d);
//result is 1.23457e+006
}
Why is the result 1.23457e+006 instead of 1.23456e+006? Does truncation occur after 6 digits?
Why am I seeing the results below?
This is how the C standard specifies the format in section [Formatted input/output functions] (C++ delegates the specification):
f,F
A double argument representing a floating-point number is converted to decimal notation in style [−]ddd.ddd, where the number of digits after the decimal-point character is equal to the precision specification. If the precision is missing, it is taken as 6; if the precision is zero and the # flag is not specified, no decimal-point character appears. If a decimal-point character appears, at least one digit appears before it. The value is rounded to the appropriate number of digits.
e,E
A double argument representing a floating-point number is converted in the style [-]d.ddde±dd, where there is one digit (which is nonzero if the argument is nonzero) before the decimal-point character and the number of digits after it is equal to the precision; if the precision is missing, it is taken as 6; if the precision is zero and the # flag is not specified, no decimal-point character appears. The value is rounded to the appropriate number of digits. The E conversion specifier produces a number with E instead of e introducing the exponent. 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.
A double argument representing an infinity is converted in one of the styles [-]inf or [-]infinity - which style is implementation-defined. A double argument representing a NaN is converted in one of the styles [-]nan* or **[-nan](n-char-sequence) - which style, and the meaning of any n-char-sequence, is implementation-defined. The F conversion specifier produces INF,INFINITY, or NAN instead of inf,infinity ,or nan, respectively.
g,G
A double argument representing a floating-point number is converted in style f or e (or in style F or E in the case of G conversion specifier), depending on the value converted and the precision. Let P equal the precision if nonzero, 6 if the precision is omitted, or 1 if the precision is zero. Then, if a conversion with style E would have an exponent of X:
if P > X ≥ -4, the conversion is with style f (or F) and precision P - (X + 1).
otherwise, the conversion is with style e (or E) and precision P - 1.
Why is the result 1.23457e+006 instead of 1.23456e+006?
Because the default precision is 6, and the value is rounded.
The default rounding mode (according to IEEE 754) is "round to nearest and ties to even". The next and previous round values of 1.234567 are 1.23457 and 1.23456. 1.23457 is nearer, so 1.234567 rounds to 1.23457.

sprintf %g specifier gives too few digits after point

I'm trying to write floating point vars into my ini file and i encountered a problem with format specifiers.
I have a float value, let it be 101.9716. Now i want to write it to my ini file, but the problem is i have another float values, which have less preceision (such as 15.85), and that values are writing to ini file in the same loop.
so i do:
sprintf(valLineY, "%g", grade[i].yArr[j]);
All my other variables become nice chars like "20" (if it was 20.00000), "13.85" (if it was 13.850000) and so on. But 101.9716 becomes "101.972" for some reason.
Can you please tell me why does this happen and how to make it "101.9716" without ruining my ideology (which is about removing trailing zeroes and unneeded perceisions).
Thanks for any help.
Why this happens?
I tested:
double f = 101.9716;
printf("%f\n", f);
printf("%e\n", f);
printf("%g\n", f);
And it output:
101.971600
1.019716e+02 // Notice the exponent +02
101.972
Here's what C standard (N1570 7.21.6.1) says about conversion specifier g:
A double argument representing a floating-point number is converted in
style f or e (or in style F or E in the case of a G conversion specifier), depending on the value converted and the precision. Let P equal the precision if nonzero, 6 if the precision is omitted, or 1 if the precision is zero. Then, if a conversion with style E would have an exponent of X:
— if P > X ≥ −4, the conversion is with style f (or F) and precision
P − (X + 1).
— otherwise, the conversion is with style e (or E) and precision P − 1.
So given above, P will equal 6, because precision is not specified, and X will equal 2, because it's the exponent on style e.
Formula 6 > 2 >= -4 is thus true, and style f is selected. And precision will then be 6 - (2 + 1) = 3.
How to fix?
Unlike f, style g will strip unnecessary zeroes, even when precision is set.
Finally, unless the # flag is used, any trailing zeros are removed from the fractional portion of the result and the decimal-point character is removed if there is no fractional portion remaining.
So set high enough precision:
printf("%.8g\n", f);
prints:
101.9716

How to loop over exact representations of floating point numbers?

I am trying to loop exactly from one floating point number to the next. Say, I need to loop from std::numeric_limits<float>::epsilon() to 1, which are both exactly representable IEEE754 numbers. My code is:
using nld = std::numeric_limits<float>;
auto h = nld::epsilon();
for (; h < 1; h = std::nextafter(h, 1)) {
std::cerr << "h: " << h << std::endl;
}
which loops indefinitely beacuse h is exactly representable, so nextafter keeps returning it. I also know that adding machine epsilon to h in a loop will not cut it: floating point numbers are not equally spaced. How do I loop over the exact representations of IEEE754 numbers?
The not equally spaced problem presents itself here:
using nld = std::numeric_limits<float>;
auto h = nld::epsilon();
for (; h < 4; h += nld::epsilon()) {
if (h = h + nld::epsilon()) {
std::cerr << "h: " << h << std::endl;
}
}
which keeps printing 2 for me
Per the comments:
The approach with nextafter is exactly what you should be doing. However, it has some complications that may lead to unexpected results.
Quoting cppreference std::nextafter:
float nextafter( float from, float to ); (1) (since C++11)
double nextafter( double from, double to ); (2) (since C++11)
long double nextafter( long double from, long double to ); (3) (since C++11)
Promoted nextafter( Arithmetic from, Arithmetic to ); (4) (since C++11)
...
4) A set of overloads or a function template for all combinations of arguments of arithmetic type not covered by (1-3). If any argument has integral type, it is cast to double. If any argument is long double, then the return type Promoted is also long double, otherwise the return type is always double.
Since your to is 1, of type int, you get overload version 4, with a return type of double. Now, it's entirely possible that given a float f, (float)nextafter((double)f, 1) is exactly equal to the original f: it's rather likely that the next representable number in type double cannot be represented in float, and that the conversion back to float rounds down.
The only overload that returns float is the one where to has type float. To use that overload, use 1.0f instead of 1.
treating them as integers will work for notmal positive floats,
negative floats will step in the wrong direction, and denormals and zero may be a special case.
eg: for positive normal floats:
float nextfloat(float in)
{
union { float f; uint32_t i; } a;
a.f=in;
a.i++;
return(a.f);
}
this is relies on the floats having the same endianness and size as the integers, here I pair float and uint32_t, but you could do the same for double and uint64_t... this could actually be a class of undefined behavior, testing its operation should probably be poart of the build process.

Hexadecimal floating point literals

Is it possible to initialize a float variable with a hexadecimal float point value in C++?
Something like this:
double d = 0x011.1; // wrong!
The Technical Specification P0245 Hexadecimal floating literals for C++ has been voted into C++17 at the ISO C++ Standards Committee in Jacksonville, Florida on February 2016.
The language C99 also has this feature, and the C++ feature is compatible.
However, as pointed by the Lưu Vĩnh Phúc's comment, the syntax 0x011.1 is not part of the standard. The binary exponent is mandatory for hexadecimal floating-point literals. One reason is to avoid ambiguity of the trailing F within 0x011.1F. Is it the hex digit F of the fractional part or the floating-suffix meaning float?
Therefore append p followed by a positive or negative decimal number, for example: 0x011.1p0.
See the more readable page floating literal page on cppreference.com.
0x | 0X hex-digit-sequence
0x | 0X hex-digit-sequence .
0x | 0X hex-digit-sequence(optional) . hex-digit-sequence
Hexadecimal digit-sequence representing a whole number without a radix separator. The exponent is never optional for hexadecimal floating-point literals: 0x1ffp10, 0X0p-1, 0x1.p0, 0xf.p-1, 0x0.123p-1, 0xa.bp10l
The exponent syntax for hexadecimal floating-point literal has the form
p | P exponent-sign(optional) digit-sequence
exponent-sign, if present, is either + or -
suffix, if present, is one of f, F, l, or L. The suffix determines the type of the floating-point literal:
(no suffix) defines double
f F defines float
l L defines long double
See also the current working draft C++17, chapter § 2.13.4 Floating literals on GitHub: https://github.com/cplusplus/draft/raw/master/papers/n4604.pdf
floating-literal:
  decimal-floating-literal
  hexadecimal-floating-literal
decimal-floating-literal:
  fractional-constant exponent-partopt floating-suffixopt
  digit-sequence exponent-part floating-suffixopt
hexadecimal-floating-literal:
  hexadecimal-prefix hexadecimal-fractional-constant binary-exponent-part floating-suffixopt
  hexadecimal-prefix hexadecimal-digit-sequence binary-exponent-part floating-suffixopt
fractional-constant:
  digit-sequenceopt . digit-sequence
  digit-sequence .
hexadecimal-fractional-constant:
  hexadecimal-digit-sequenceopt . hexadecimal-digit-sequence
  hexadecimal-digit-sequence .
exponent-part:
  e signopt digit-sequence
  E signopt digit-sequence
binary-exponent-part:
  p signopt digit-sequence
  P signopt digit-sequence
sign: one of
  + -
digit-sequence:
  digit
  digit-sequence ’opt digit
floating-suffix: one of
  f l F L
1 A floating literal consists of an optional prefix specifying a base, an integer part, a radix point, a fraction part, an e, E, p or P, an optionally signed integer exponent, and an optional type suffix. The integer and fraction parts both consist of a sequence of decimal (base ten) digits if there is no prefix, or hexadecimal (base sixteen) digits if the prefix is 0x or 0X. The literal is a decimal floating literal in the former case and a hexadecimal floating literal in the latter case. Optional separating single quotes in a digit-sequence or hexadecimal-
digit-sequence are ignored when determining its value. [ Example: The literals 1.602’176’565e-19 and 1.602176565e-19 have the same value. — end example ] Either the integer part or the fraction part (not both) can be omitted. Either the radix point or the letter e or E and the exponent (not both) can be omitted from a decimal floating literal. The radix point (but not the exponent) can be omitted from a hexadecimal floating literal. The integer part, the optional radix point, and the optional fraction part, form the significand of the floating literal. In a decimal floating literal, the exponent, if present, indicates the power of 10 by which the significand is to be scaled. In a hexadecimal floating literal, the exponent indicates the power of 2 by which the significand is to be scaled. [ Example: The literals 49.625 and 0xC.68p+2 have the same value. — end example ] If the scaled value is in the range of representable values for its type, the result is the scaled value if representable, else the larger or smaller representable value nearest the scaled value, chosen in an implementation-defined manner.
The type of a floating literal is double unless explicitly specified by a suffix. The suffixes f and F specify float, the suffixes l and L specify long double. If the scaled value is not in the range of representable values for its type, the program is ill-formed.
As unwind has advised, you can use strtof(). The following snippet decodes Hexadecimal floating literals (without C++17):
#include <iostream>
#include <cstdlib>
#include <cstdio>
int main(int argc, char *argv[])
{
if (argc != 2)
{
std::cout <<"Usage: "<< argv[0] <<" 0xA.Bp-1 => Decode hexfloat" "\n";
return 1;
}
long double l;
double d;
float f;
std::cout <<"Decode floating point hexadecimal = "<< argv[1];
//std::istringstream(argv[1]) >> std::hexfloat >> d;
l = std::strtold(argv[1],NULL); if(errno == ERANGE) std::cout << "\n" "std::strtold() range error";
d = std::strtod (argv[1],NULL); if(errno == ERANGE) std::cout << "\n" "std::strtod() range error";
f = std::strtof (argv[1],NULL); if(errno == ERANGE) std::cout << "\n" "std::strtod() range error";
std::cout <<"\n" "long double = "<< std::defaultfloat << l <<'\t'<< std::hexfloat << l
<<"\n" "double = "<< std::defaultfloat << d <<'\t'<< std::hexfloat << d
<<"\n" "float = "<< std::defaultfloat << f <<'\t'<< std::hexfloat << f <<'\n';
}
No, C++ doesn't support that for literals, it's not part of the standard.
A non-portable solution is to use a compiler that adds this as an extension (GCC does this).
A portable workaround is to parse them from string literals at runtime using e.g. strtof() or strtod() for double.
As pointed out in a comment, you can also opt to store the constants in a C file. Doing so requires that you have access to a C99 compiler though, since hex float literals is a C99-level feature. Since environments with a new C++ compiler but without a C99 compiler (read: Visual Studio) are quite common, that might not be a workable solution.
Update: C++17 supports hexadecimal floating point literals.

C++ printf printing doubles reads as 0

So I want to use printf so that I can make columns line up but printf can't seem to print doubles that need scientific notation. It just comes out as a 0 but with cout it comes out fine. 'in' and 'fn' are structs 'x' 'y' and 'z' are doubles
Code
printf("Facet Normal: %lf %15lf %15lf\n", in->fn.x, in->fn.y, in->fn.z);
cout << "cout test: " << in->fn.x << endl;
Output
Facet Normal: -0.000000 -0.894426 0.447215
cout test: -9.6137e-08
I can't seem to get printf to work correctly. I had the entire function working correctly with cout but like I said, I'd like things to line up niftily.
Edit:
As Oli said, using %e does get it to print correctly. By using %e throughout though it puts everything in scientific notation and a lot of the numbers in the data set don't in reality really need it. Cout seems to convert between %lf and %e as needed. Is there an easy way to get printf to get this behavior as well?
Answer:
%f is for both float and double (since float arguments are promoted to double);
%lf is for long double. f prints with no exponent, e prints with an exponent, and
g uses whichever looks better (following specific rules).
– Keith Thompson
%g gets the exact behavior I was looking for!
As the std::printf() reference says, just use %e:
std::printf( "One double in decimal scientific notation! %e" , my_double );
But the correct C++ way is to use std::cout and some manipulators, std::scientific in this case:
std::cout << "One double in decimal scientific notation!" << std::scientific << my_double;
Note that the format of std::cout forms part of its state, that is, you only have to configure it once, the format is applied to any output operation after the setting, and before other format change:
std::cout << std::scientific;
std::cout << std::pow( 10.0 , 10.0 ) << std::endl;
std::cout << std::pow( 10.0 , 20.0 ) << std::endl;
std::cout << std::pow( 10.0 , 30.0 ) << std::endl;
1e11
1e21
1e31
It seems you want to get the "best" formatting (which is the default for std::ostream): you can use %g (%Lg for long double) to have the formatting function decide how the values should be formatted. There are four format specifiers:
%f for fixed point notation (the format used by std::fixed for streams).
%e for scientific formatting (the format used by std::scientific for streams).
%g for the "best" version of fixed and scientific (the default for streams and since C++11 std::defaultfloat).
%a for an exact/hex representation of the floating point number (since C++11 std::hexfloat).
The formatting flags can used both in lowercase and uppercase to indicate whether any characters should be lowercase or uppercase (e.g. e vs. E). Note that the l length specifier is actually not relevant for the floating point formatting. You might need to use L, though, when formatting long double
If you want to control the output from std::cout, use setw() and setfill().
http://www.cplusplus.com/reference/iomanip/setw/
You can also set the precision, etc. I will leave that to you to explore.