From: Kevlin Henney (kevlin_at_[hidden])
Date: 2001-02-19 04:11:09
In message <3A90B900.E6B07CE5_at_[hidden]>, Greg Chicares
>Would it be worthwhile to modify lexical_cast to reflect the inherent
>precision of floating-point numbers?
Possibly, if it can be done consistently and uniformly.
>I believe that
> lexical_cast<std::string, PODType)
> lexical_cast<PODType, std::string)
>are already inverse operations for non-floating-point POD types.
Only if operator<< and operator>> are true inverses, and there is
currently no requirement that they should be.
>motivation is to make that true--or, equivalently, to make lexical_cast
>a value-preserving conversion--for floating-point types as well.
The value preserving issue has come up before (IIRC, Dave Abrahams
alerted me to one at the Toronto WG21 mtg). However, there are a couple
of issues to address: (1) built-in casts do not always have value-
preserving semantics (and hence are not always inverses), and (2) how
practical is it to root out all of the edge cases?
>I believe it suffices to add
> const int prec0 = std::numeric_limits<Source>::digits10;
> const int prec1 = std::numeric_limits<Target>::digits10;
> interpreter.precision(1 + max(prec0, prec1)); // see Notes
>to lexical_cast.hpp right after 'interpreter' is defined. Thus, for
>double d, this statement would be true:
> d == lexical_cast<double>(lexical_cast<std::string>(d));
>except in degenerate cases like NANs.
This works fine for float, double and long double, but have you tried it
with std::complex? The results are unfortunate :-(
digits10 is 0 for any non-specialised use of numeric_limits, which is
the case for std::complex, which means that the stream is given an
output precision of 1. So, other numeric types suffer as a result, which
I think is a worse scenario than accepting that when you play with
floating point numbers there are some limits to your expectations. This
is already in line with what programmers are taught about floats from
the moment they learn any such language.
That said, there may be a solution if you select how you set the
precision based on numeric_limits<>::is_specialized. This would
discriminate in favour of built-ins, but at least would not actively
discriminate against other types. However, I have not tried this
A couple of other implementation issues you might also want to consider:
- std::max is not defined for MSVC, therefore must be done by hand.
- <limits> is not defined for g++, so omit no support for this on g++.
Kevlin Henney phone: +44 117 942 2990
Curbralan Limited mobile: +44 7801 073 508
mailto:kevlin_at_[hidden] fax: +44 870 052 2289
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk