
-----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of Fernando Cacciola Sent: Thursday, June 09, 2011 4:35 AM To: boost@lists.boost.org Subject: Re: [boost] MS VC10 std::numeric_limits<float>::max_digits10 iswrong for float
On 08-Jun-11 9:32 PM, Stephan T. Lavavej wrote:
Separately, Dinkumware has told me that 8 really is the right answer here, not 9.
Hmmm... then if they are right, we're all wrong, because 9 is the number I've always seen as correct.
OTOH, we *could* have been all wrong, all alone, since this is the sort of thing that just gets perpetuated from publication to publication and mouth to mouth.
Do they explained why? [Are P.J. and Pete still the ones behind these things?]
Well I was surprised to notice the value 8 and so I re-ran my existing loopback test (that had previously worked OK for float, but not for double). (This test was purely for convenience - takes all night to run, brute force is possible for float whereas for double test all possible values would take 35 years at current processor speeds! (though a random test did reveal loopback fails with doubles with the Dinkumware library, allegedly a feature, not a bug). It was devised to check if loopback (output to a string and reading back in) works OK (a separate issue, but if max_digits10 is wrong, loopback will fail). This issue is NOT about loopback (which is NOT guaranteed by the C++ Standard) but about max_digits10. So I ran a much simple test and found quite a few values of float that give the same decimal digit string for 1-bit different binary patterns. But it only takes one value that 'fails' for 8 to be wrong, and a simple example is below: union ful { // Used to enable output of float in hex. float f; unsigned long u; }; int main() { ful f1; f1.f= 1.10000006e-032f; ful f2; f2.f = 1.10000014e-032f; // 1 bit greater in FP binary pattern, see hex display below cout << "f1 " << setprecision(8) << "precision 8 " << f1.f << endl; cout << "f1 "<< setprecision(9) << "precision 9 " << f1.f << endl; cout << "f1 " << hex << f1.u << endl; cout << "f2 " << setprecision(8) << "precision 8 " << f2.f << endl; cout << "f2 " << setprecision(9) << "precision 9 " << f2.f << endl; cout << "f2 " << hex << f2.u << endl; return 0; } f1 precision 8 1.1000001e-032 f1 precision 9 1.10000006e-032 f1 a647609 f2 precision 8 1.1000001e-032 <<<<<<<<<< note this is the same as f1 above using 8. f2 precision 9 1.10000014e-032 <<<< but f1 and f2 are different using 9. f2 a64760a <<<<<<<<<< note f2 really is one bit greater and so should have a different decimal digits string representation. I hope this is convincing - I conclude that Kahan was right, and is still is ;-) Paul --- Paul A. Bristow, Prizet Farmhouse, Kendal LA8 8AB UK +44 1539 561830 07714330204 pbristow@hetp.u-net.com