[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: |
Thu, 1 Dec 2016 15:11:00 +0100 |
On Thu, 1 Dec 2016 02:03:22 +0000 Greg Chicares <address@hidden> wrote:
GC> On 2016-11-30 15:08, Vadim Zeitlin wrote:
GC> > On Wed, 30 Nov 2016 08:15:56 +0000 Greg Chicares <address@hidden> wrote:
GC> >
GC> > GC> On 2016-11-30 00:27, Greg Chicares wrote:
GC> > GC> [...]
GC> > GC> > expected: 70000000 * 0.04551 = 3185700.00 exactly
GC> > GC> > observed: 3185700.00 with old_bin [exactly as expected]
GC> > GC> > observed: 3185699.99000000022352 with new_bin [anomaly]
GC>
GC> Correction: the 'old_bin' and 'new_bin' labels were reversed, so,
GC> at least for this particular discrepancy, the result is actually
GC> improved by using the new table.
Ah, I feel significantly less bad now.
GC> > GC> > lmi rounds the calculated seven-pay premium down to cents, so a
GC> > GC> > difference of 1 ulp in the binary number read from the table could
GC> > GC> > account for this anomaly. I imagine a 1 ulp difference could arise
GC> > GC> > in table_impl::parse_single_value() [showing only the most relevant
GC> > GC> > lines]:
GC> > GC> >
GC> > GC> > auto const res_int_part = strict_parse_number(current);
GC> > GC> > auto const res_frac_part = strict_parse_number(res_int_part.end
+ 1);
GC> > GC> >
GC> > GC> > double value = res_frac_part.num;
GC> > GC> > value /= std::pow(10, *num_decimals_);
GC> > GC> > value += res_int_part.num;
GC> > GC> > return value;
GC>
GC> 0.0455099999999999949019 Saved7PPRate <-- read from OLD binary table
GC> 0.0455100000000000018407 Saved7PPRate <-- read from NEW binary table
GC>
GC> 0.0455100000000000000000
GC> - 0.0455099999999999949019
GC> = 0.0000000000000000050981
GC> 50981 / 455100000000000000000 = 1.1e-16 ~= double-precision epsilon
Yes, the first number (the old one) is 3FA74D1633482BE8 in IEEE-754 64 bit
format, while the second one is 3FA74D1633482BE9, so there is indeed
exactly one bit of difference between them.
GC> New hypothesis: The original binary tables may be slightly inaccurate.
Yes, they are. The worst is that I now remember already running into this
problem and even, I think, discussing it with you back when I was working
on this. We concluded the same thing then: the values in the old binary
tables could be off by one ULP, presumably due to a bug in Turbo C++ CRT,
and we should trust the text, not binary, representation because of this.
GC> > Yes, this would work if you don't mind value_cast<> overhead.
GC>
GC> Doesn't any modern compiler optimize all the overhead away, leaving only
GC> a call to std::strtod()?
I'm not sure about it. In any case, it seems a call to strtod() ought to
be more expensive than one pow() call, one division and one addition. Of
course, we probably don't care about performance here that much anyhow.
Regards,
VZ
- Re: [lmi] rate_table_tool: merge a whole directory,
Vadim Zeitlin <=