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: Greg Chicares
Subject: Re: [lmi] rate_table_tool: merge a whole directory
Date: Wed, 30 Nov 2016 00:27:04 +0000
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Icedove/45.3.0

On 2016-11-23 01:29, Greg Chicares wrote:
> Proprietary rate tables are distributed along with our free software.
> These tables can be stored in two interconvertible formats:
>  - binary: not human-readable, which is good for distribution to
>    outsiders who should be discouraged from extracting proprietary
>    data, but inconvenient for internal maintenance; and
>  - human-readable text, which is better for maintenance but not for
>    external distribution.
> Our plan is to store tables as text in a proprietary git database,
> and use 'rate_table_tool' to convert them to binary for distribution.

Testing this, I see some anomalies. Let
  {old, new} be rate databases, and
  {txt, bin} be text and binary formats.
I convert
  old_bin --> old_txt --> new_bin
and then run a system test using new_bin in place of old_bin, and
observe several regression errors.

Nevertheless, if I convert
  old_bin --> old_txt --> new_bin
as above, then
  new_bin --> new_txt
then all old_txt and new_txt files are identical. I can't see any
anomaly there, but clearly old_bin and new_bin are not identical,
so either (1) conversion to text involves rounding that removes
any discrepancies, or (2) the code in 'actuarial_table.cpp' behaves
differently than that in 'rate_table.cpp'.

Digging into a particular, simple example [this is proprietary
test case 'XXXXc2005.000000009.test' where "XXXX" = redaction]:

  issue age 39
  SevenPayTable 262
  table '262.txt' contains the line:
    39  0.04551
  specified amount 70000000
  expected: 70000000 * 0.04551 = 3185700.00 exactly
  observed: 3185700.00 with old_bin [exactly as expected]
  observed: 3185699.99000000022352 with new_bin [anomaly]

lmi rounds the calculated seven-pay premium down to cents, so a
difference of 1 ulp in the binary number read from the table could
account for this anomaly. I imagine a 1 ulp difference could arise
in table_impl::parse_single_value() [showing only the most relevant
lines]:

    auto const res_int_part = strict_parse_number(current);
    auto const res_frac_part = strict_parse_number(res_int_part.end + 1);

    double value = res_frac_part.num;
    value /= std::pow(10, *num_decimals_);
    value += res_int_part.num;
    return value;

My hypothesis then, comparing floating-point numbers for strict
equality, is that:
  assert(0.04551 != 4551 / 10000)

I suspect it's necessary to parse text as above in order to write
helpful diagnostics, but I think the return value should be the
applicable character substring converted by some other means, e.g.,
  value_cast<double>(std::string const&)
I can figure out what conversion we need. Vadim, can you show me
how to get a std::string object containing the formatted single
number that is to be converted (because I'm snow-blind after
staring at all these pointers)?

(The early exit that I added in case the datum really is integral
seems safe: converting strings to integers is exact.)




reply via email to

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