Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is the sprintf_s giving different result in different versions of Visual Studio?

sprintf_s(buf, "%.*f", 14, 0.182696884245135);

in VS2008 = 0.18269688424514

in VS2015 = 0.18269688424513

Was the behavior for sprintf_s changed? How can I get the old behavior?

like image 488
John Mcdock Avatar asked Aug 26 '15 16:08

John Mcdock


2 Answers

We rewrote the floating point parser and formatter for the Universal CRT and Visual C++ 2015 to improve correctness. See the Breaking Changes in Visual C++ documentation for Visual C++ 2015; there is a section entitled "Floating point formatting and parsing."

The Visual C++ 2015 result is the correctly rounded result. The input string 0.182696884245135 is converted to the following double precision value, which is the closest representable value:

0.18269688424513'49994693288181224488653242588043212890625

Note the tick mark after the 14th fractional digit. The 15th digit is a 4, so when formatting the number with 14 fractional digits, the number is "rounded down" (or truncated), not up.

The Visual C++ 2008 result is incorrect. I do not know whether error was introduced during parsing or formatting. There is no way to get the old, incorrect behavior with the Universal CRT and Visual C++ 2015.

like image 147
James McNellis Avatar answered Nov 20 '22 12:11

James McNellis


Vs2008 was using 80bit floating point literals and was rounding this more precise value when converting to a double.

Vs2015 doesn't do this and merely truncates the literal.

I believe you can toggle between the two schemes by changing the compiler settings.

like image 23
Bathsheba Avatar answered Nov 20 '22 13:11

Bathsheba