Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
770 views
in Technique[技术] by (71.8m points)

visual studio - C++ Rounding behavior consistency for ties with sprintf

I have a C++ program that runs on both Windows/Linux. On Windows the program is compiled with Visual Studio 2012 and Linux it is compiled with GCC. When converting doubles to strings using sprintf Visual Studio is using a different rounding method than the GCC compiler for ties - ie decimals ending in a 5.

Visual Studio compiler appears to perform round half away from zero while GCC does round even aka bankers rounding.

Round even is the desired behavior.

Is it possible to change the rounding behavior used for sprintf format strings in visual studio / windows? As I need to make the rounding behave consistently between the two.

Here is a small sample C++ program that illustrates the above described behavior:

int main()
{   
   char buffer[100];

   double x;
   for (x = -0.5; x <= 10.5; x += 1.0)
   {
      sprintf(buffer,"%4g %.0f
", x, x);

      std::cout << buffer;
   }  

   return 0;
}

Windows output. Numbers are rounded away from zero:

windows

OSX output compiled using xCode. Numbers are rounded using round even towards the even number:

osx

OSX output:

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

This is implementation defined behavior from the draft C11 standard section 7.21.6.1 The fprintf function which covers sprintf with respect for format specifiers and also C++ since the C++ standard relies on the C standard for stdio functions, it says for the f format specifier:

The value is rounded to the appropriate number of digits.

this is also covered by defect report 211 which added the following:

The accuracy of the floating-point operations ( +, -, *, /) and of the library functions in and that return floating-point results is implementation defined, as is the accuracy of the conversion between floating-point internal representations and string representations performed by the libray routine in , and . The implementation may state that the accuracy is unknown.

the article Inconsistent Rounding of Printed Floating-Point Numbers covers this inconsistency in great details and mentions that:

glibc printf() has been updated to take the current IEEE rounding mode into account. This was done in version 2.17; I just tested it on version 2.18. In doing it this way of course, round-to-nearest/round-half-away-from-zero is still not an option, so this doesn’t help you make its output consistent with other platforms.

but as said this does not help with cross platform consistency.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...