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 08:15:56 +0000
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Icedove/45.3.0

On 2016-11-30 00:27, Greg Chicares wrote:
[...]
>   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)?

I think I've figured out the answer to the last question (though I
haven't yet tested the conversion code in this experimental patch):

----------8<----------8<----------8<----------8<----------8<----------
diff --git a/rate_table.cpp b/rate_table.cpp
index c705122..5271da3 100644
--- a/rate_table.cpp
+++ b/rate_table.cpp
@@ -26,6 +26,7 @@
 #include "alert.hpp"
 #include "crc32.hpp"
 #include "path_utility.hpp"
+#include "value_cast.hpp"
 
 #include <boost/filesystem/convenience.hpp>
 #include <boost/filesystem/exception.hpp>
@@ -1567,6 +1568,8 @@ double table_impl::parse_single_value
     ,int& line_num
     )
 {
+    char const* beginning = current;
+
     // The number of spaces before the value should be at least one,
     // and no greater than (gap_length, plus one if the number of
     // decimals is zero, because get_value_width() assumes, contrary
@@ -1653,6 +1656,12 @@ double table_impl::parse_single_value
     value /= std::pow(10, *num_decimals_);
     value += res_int_part.num;
 
+//    std::string s(start, current);
+// Attempt to convert string '  0  0.25751' from type std::string to type 
double
+// failed on terminal substring '  0.25751'.
+    std::string s(beginning, current);
+    return value_cast<double>(s);
+
     return value;
 }
 
---------->8---------->8---------->8---------->8---------->8----------

IOW, in this function:
  double table_impl::parse_single_value
    (char const* start
    ,char const*& current
    ,int& line_num
    )
at first I guessed that the 'start' argument pointed to the beginning of
the single value to be parsed, but it actually points to the beginning
of the current line of text, i.e., '  0  0.25751' for age 0. Instead,
the current datum begins at the original value of argument 'current'.

Apparently the 'start' and 'line_num' arguments are used only for
writing diagnostics. If that's correct, BTW, then why is 'line_num'
passed by reference?




reply via email to

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