Subject: [Boost-bugs] [Boost C++ Libraries] #4334: Patch lexical_cast (#4184 + fix to allow casts from string representations of floats to ints)
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2010-06-11 05:56:37
#4334: Patch lexical_cast (#4184 + fix to allow casts from string representations
of floats to ints)
------------------------------------------+---------------------------------
Reporter: admin@⦠| Owner: nasonov
Type: Patches | Status: new
Milestone: Boost 1.43.0 | Component: lexical_cast
Version: Boost 1.44.0 | Severity: Problem
Keywords: float int lexical conversion |
------------------------------------------+---------------------------------
This patch (hopefully) fixes
[https://svn.boost.org/trac/boost/ticket/4119] (more details explained in
my reply in that ticket). Additionally, this patches lexical_cast to
convert string representations of floats to integers properly.
An attempt to convert a string representation of a floating point unit
("42.5", "500.125", etc) to an integer would throw a bad cast exception.
This happened because the operator>> members in the lexical_cast stream
classes returned:
{{{
return stream >> output && stream.get() == Traits::eof();
}}}
The boost::lexical_cast function evalutes this return value, throwing an
exception if the return was false. The second half of the return value,
''stream.get() == Traits::eof();'', returns false when boost::lexical_cast
is invoked to convert a string representation of a float to an integer,
because extraction from the stream to an integer would stop once the
decimal point was encountered.
For example, if "17.6" was being converted from a character sequence to an
integer, the ''stream >> output'' call would extract "17" from the the
stream to the integer. The last two characters, ".6", would still be in
the stream, causing ''stream.get() == Traits::eof();'' to return false.
The solution is pretty simple - when converting from a string
representation of a floating point unit to an integer, we simply extract a
float from the stream after extracting the integer. This leaves us with an
integer, a floating point unit (range 0 to 1), and an empty stream.
The floating point unit is rounded (floored if below 0.5, ceiled if above
0.5. The float is always floored if adding it to the integer would cause
the integer to overflow), and then added to the integer.
Results of a test program, using unpatched boost::lexical_cast:
{{{
wash_at_Pegasus:~/sandbox/concept-test/boost$ ./string_float_to_int_unpatched
"42.6" as int 0
"2147483646.9999" as int 0
"800.0001" as int 0
}}}
After:
{{{
wash_at_Pegasus:~/sandbox/concept-test/boost$ ./string_float_to_int_patched
"42.6" as int 43
"2147483646.9999" as int 2147483646
"800.0001" as int 800
}}}
-- Ticket URL: <https://svn.boost.org/trac/boost/ticket/4334> Boost C++ Libraries <http://www.boost.org/> Boost provides free peer-reviewed portable C++ source libraries.
This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:03 UTC