lmi
[Top][All Lists]
Advanced

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

[lmi] x86_64 expm1() and log1p() differ by platform


From: Greg Chicares
Subject: [lmi] x86_64 expm1() and log1p() differ by platform
Date: Thu, 19 May 2022 11:25:51 +0000
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.8.0

The results of 'make system_test' differ between pc-linux-gnu and msw,
but only for monthly interest rates, and only in the sixteenth significant
decimal: i.e., they're off by something like one ulp. It would be most
desirable for them to match perfectly, because that target builds several
times as fast for pc-linux-gnu as opposed to (wine-emulated) msw.

We've always cared about differences as small as one ulp because they can
grow over time, resulting in material discrepancies in an illustration's
later years. For regression testing, it's important to know where the
discrepancies begin, so reducing the precision in '.test' output files to
hide the problem is not a good idea. (Using a currency class for insurance
calculations, and showing integral cents in '.test' files, doesn't "hide"
problems--it eliminates them, removing spurious representation error.
Such amounts are still shown to DECIMAL_DIGIT precision; it just so
happens that they're integers, because they truly represent integral cents
in the problem domain.)

This throwaway branch:
  https://git.savannah.nongnu.org/cgit/lmi.git/log/?h=odd/expm1_log1p
shows that these discrepancies can be eliminated by implementing expm1()
and log1p() ourselves. But it is not trivial to do so accurately. I had
hoped that __builtin_ versions would provide high-quality cross-platform
implementations, but it seems clear that they simply forward to the C RTL.

One option is to import a trusted implementation such as glibc's into our
repository. I would confidently assume that glibc's is of higher quality
than MinGW-w64's. But that would take work, and we'd wind up with an
an implementation that's frozen in time unless we spend effort keeping it
up to date.

Instead, I plan to purge the discrepant fields from class Ledger, of which
the regression-tested '.test' output files are a DECIMAL_DIG-precision
serialization. The rationale is that monthly interest rates never truly
belonged there. Account-value accumulations create and temporarily store
a great deal of intermediate data, from which a comparatively small
Ledger object is extracted; all reports use only this extract. Reports
display annual interest rates, but never their monthly equivalents.
Whenever it is useful to see these internals, a '.monthly_trace' file
should be generated: by its nature, that trace of ephemeral internal
calculations shows details that are deliberately omitted from the Ledger
object. No one would use the '.test' files for this purpose. Thus,
removing monthly interest rates from class Ledger, where they're just
inconvenient clutter, is a desirable goal in itself. If we ever really
want to, we can still replace the MinGW-64 transcendentals: that option,
and the one chosen here, are orthogonal.


reply via email to

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