lmi
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [lmi] rate_table_tool: merge a whole directory


From: Vadim Zeitlin
Subject: Re: [lmi] rate_table_tool: merge a whole directory
Date: Mon, 5 Dec 2016 01:18:21 +0100

On Sun, 4 Dec 2016 23:03:14 +0000 Greg Chicares <address@hidden> wrote:

GC> I'm surprised. Separating a string like 'n.nnnnn' (with no more than about
GC> ten digits in practice) into integral and fractional parts leaves no room
GC> for any numerical discrepancy, but this algorithm does:
GC> 
GC>     double value = res_frac_part.num;
GC>     value /= std::pow(10, *num_decimals_);
GC>     value += res_int_part.num;
GC> 
GC> Given that num_decimals_ is a small integer, I'd hope that std::pow() would
GC> return an exact integer value... but IIRC that wasn't reliably true for 
older
GC> versions of MinGW; and I'm not sure the standard requires that to be true,
GC> though it's certainly a QoI issue if it's not true.
GC> 
GC> However, more seriously, if we do what the code literally says, then given
GC> "1.23456", we form the integer 23456, divide it by 100000, round it to
GC> double precision, and store it. Then we add an integer to it and round the
GC> result, which causes the loss of some trailing bits in the fractional part.
GC> 
GC> I don't think the C++ standard guarantees that the result is correctly
GC> rounded. Of course, it doesn't forbid that, either. Maybe contemporary
GC> compilers are smart enough to fuse all the floating-point arithmetic
GC> into one atomic operation.

 I didn't check this, but I don't think so. I'm also not sure if the code
above can be guaranteed to work correctly (although it seems to me that
with only 10 significant digits, there should be no way for 1 ULP error in
the 16th or 17th digit to affect the result), all I can say is that it does
work for all numbers with up to 10 digits of precision on the platforms
where I tested it.

GC> >  I won't repeat the arguments I had already made (and even several times, 
I
GC> > believe) for switching to the use of SSE instructions in lmi, but it's 
just
GC> > clearly annoying to have different (and non-standard, without speaking of
GC>                                           ^^^^^^^^^^^^ ?
GC> > slower) behaviour in lmi code than with the other compilers/architectures.
GC> > I realize switching to SSE is not a priority (and probably will never be),
GC> > but it would still be nice to stop using x87.
GC> 
GC> "non-standard"? If my analysis above is incorrect, and the C++ standard
GC> guarantees that the code above produces results identical to strtod(),
GC> then please point out my mistake.

 No, sorry, I didn't mean this particular snippet of code, but rather that
there are well-known problems with using x87 due to differing precision of
memory and registers in this case (64 vs 80 bits), which can and does
result in a significant change to the computation results just because the
code is compiled slightly differently.

 In this particular case, I don't really know why does x87 code start
giving wrong results with just 6 digits, this definitely seems suspicious
to me, but I didn't think it was worth spending time on investigating this
further, I was just glad to find why I wasn't able to reproduce your
results in my MSVC build. I could look at it in even more details if you're
curious, of course.

 Regards,
VZ


reply via email to

[Prev in Thread] Current Thread [Next in Thread]