| -----Original Message----- | From: [EMAIL PROTECTED] | [mailto:[EMAIL PROTECTED] Behalf Of Daniel Spangenberg | Sent: Tuesday, August 19, 2003 9:25 AM | To: [EMAIL PROTECTED] | Subject: [boost] Re: Insufficient significant digits using lexical_cast
In the absence of a C99 or numeric_limits significant decimal digits value (and don't forget what is needed is effectively an 'unrounded' value with some 'noisy' guard digits at the end, not just digits10) some tests show that the following if(std::numeric_limits<Target>::is_specialized && std::numeric_limits<Target>::radix == 2) { stream.precision(2 + std::numeric_limits<Target>::digits * 301/1000); } else if(std::numeric_limits<Source>::is_specialized && std::numeric_limits<Source>::radix == 2) { stream.precision(2 + std::numeric_limits<Source>::digits * 301/1000); } uses the correct number of significant decimal digits for ALL builtin bool, char, int and floating point types: And a loopback test like: l == lexical_cast<T>(lexical_cast<string>(l)) is true (correct) for at least some selected values - and I wager a couple of beers for all non-NaN non-Inf values ;-). Possibly a comment warning of possible trouble here would be helpful? // if neither specialized, or unusual radix, then use default stream precision of 6? // Warning: a loopback like // l == lexical_cast<T>(lexical_cast<string>(l)) may be false I believe a test radix == 2 is appropriate because is_iec599 (IEEE754) would fail for integer types, which actually work correctly with the above formula. Paul Dr Paul A Bristow, hetp Chromatography Prizet Farmhouse, Kendal, Cumbria, LA8 8AB UK +44 1539 561830 Mobile +44 7714 33 02 04 mailto:[EMAIL PROTECTED] For the curious I used: template <typename T> bool test(T l) { cout << l << ' '; string sl = lexical_cast<string>(l); cout << sl << ' '; T ll = lexical_cast<T >(sl); cout << ll << (l == lexical_cast<T>(lexical_cast<string>(l))) // Convert type T to string and back to T. << endl; // eg for long 2147483647 2147483647 2147483647true return (l == lexical_cast<T>(lexical_cast<string>(l))); } // test template <typename T> bool tests() { if (numeric_limits< T >::is_specialized) { cout << numeric_limits< T >::digits << ' ' << numeric_limits< T >::digits10 << ' ' << 2 + std::numeric_limits<T>::digits * 301/1000 << endl; } else { cout << "Not specialized!" << endl; } return // for a few sample values. test< T >(numeric_limits< T >::max()) // max && test< T >(T(1)) // unity && test< T >(T(0)) // zero && test< T >(T(-1)) // -1 && test< T > (numeric_limits< T >::min()); // min } // tests and tests<bool> (); tests<char> (); tests<unsigned char> (); tests<short> (); tests<unsigned short> (); tests<int> (); tests<long> (); tests<unsigned long> (); tests<float> (); tests<double> (); tests<long double> (); _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost