Boost logo

Boost :

Subject: Re: [boost] Floating point truncation bug in qi::float_
From: Paul A. Bristow (pbristow_at_[hidden])
Date: 2010-09-29 04:53:18


> -----Original Message-----
> From: boost-bounces_at_[hidden] [mailto:boost-bounces_at_[hidden]]
> On Behalf Of Jeffrey Lee Hellrung, Jr.
> Sent: Tuesday, September 28, 2010 10:26 PM
> To: boost_at_[hidden]
> Subject: Re: [boost] Floating point truncation bug in qi::float_
>
> On 9/28/2010 1:12 PM, Henry Tan wrote:
> > Hi I am using boost 1.4.1 Spirit::Qi.
> >
> > I think we have a floating point truncation bug in the qi::float_
parser.
> > I attached a simple program to repro the bug.
> >
> > Below are some examples of an input floating point gets truncated (=>)
> > by the qi::float_:
> >
> > 12312321421421 => 12312321720320.000000
> > 123123214 => 123123216.000000
> > 123233.4124 => 123233.406250
> >
> > I don't see the same issue with the qi::double_.
> >
> > Wondering if this is a known issue?
> >
> > Regards,
> >
> > HTan
>
> Without being too familiar with the qi::float_ parser, I would guess it
rounds
> rather than truncates.
>
> Keep in mind that floats are typically 32-bit single precision [1], hence
have only
> 24 significant bits (a bit more than 7 significant decimal digits), which
is
> consistent with your results.
>
> On the other hand, doubles are typically 64-bit double precision [2],
hence have
> 53 significant bits (a bit under 16 significant decimal digits), so the
first 2 inputs
> above would be stored exactly, and the 3rd one would be pretty close.
>
> - Jeff
>
> [1] http://en.wikipedia.org/wiki/Single_precision_floating-point_format
> [2] http://en.wikipedia.org/wiki/Double_precision_floating-point_format

With newer compiler/standard libraries

#include <limits>

allows you to automatically get all the potentially significant digits using
the new max_digits10

  cout.precision(std::numeric_limits<double>::max_digits10);

And remember that *input* of a string of decimal digits from a stream is
*not guaranteed* by the C++ Standard
to produce the nearest representable value. It could be one bit up or one
bit down. It does work to exact representation (as the compiler does from
literals) nearly all the time (and I have confirmed that for floats it is
all the time - you can test every single floating point value in a
reasonable time - overnight!) but not necessarily for double. For
Microsoft, there are tiny range of doubles for which the result is 1 bit
'wrong'. The workaround is simple - use scientific format with max_digits10
. Details at

http://lab.msdn.microsoft.com/ProductFeedback/viewfeedback.aspx?feedbackid=c
1f1ea71-2f7b-4ac1-b75b-68370c367aae

aka http://tinyurl.com/rvp4j

It's a feature, not a bug.

Paul

---
Paul A. Bristow,
Prizet Farmhouse, Kendal LA8 8AB  UK
+44 1539 561830  07714330204
pbristow_at_[hidden]

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk