[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [lmi] Numerics
From: |
Vadim Zeitlin |
Subject: |
Re: [lmi] Numerics |
Date: |
Tue, 29 Mar 2016 00:08:51 +0200 |
On Mon, 28 Mar 2016 21:49:38 +0000 Greg Chicares <address@hidden> wrote:
GC> (Here's the motivation. If a textcontrol is to accept an interest rate in
GC> a range like [0.03, 0.07], and treat input outside that range as invalid,
GC> then it would be naive to compare the input directly to either bound: if
GC> "0.07" is correctly entered and the machine translates that text string to
GC> 0.07000000000000001 (e.g.), and compares it to a bound represented as, say,
GC> 0.06999999999999999, then we shouldn't reject it, because it's the user's
GC> best attempt at specifying the upper-limit interest rate. Therefore, the
GC> bounds are "adjusted" outward by one ulp.)
Unless I'm missing something, the naïve solution should work as long as
the values are rounded up to the appropriate number of digits. Wouldn't
this be simpler?
GC> Clearly C99 nextafter() would be preferable, but I think it was unavailable
GC> with MinGW gcc-3.x at the time I wrote that. Yet is the "× (1 + ε)" trick
GC> actually incorrect (except for special values as noted above)? Isn't it
GC> generally true (modulo those exceptions) that nextafter(X) / X is 1 + ε?
I'm not sure. I can't find any normative documentation stating this. And
Boost implementation certainly does something much more complicated than
multiplying by 1+ε, even for non denormals, see
https://github.com/boostorg/math/blob/5eb74b83c0914c5c1a820e679e49086ad66dcce9/include/boost/math/special_functions/next.hpp#L108
GC> I imagine that I preferred multiplying by one plus epsilon because it's
GC> easier to read and write, and especially because it's harder to get wrong
GC> than twiddling the bits. Of course, nextafter() has those advantages with
GC> none of the disadvantages, and we do seem to have it in MinGW-w64 gcc now:
Yes, and it's not only C99 but C++11 as well, so it's even supported by
MSVS.
GC> Getting rid of the remaining uses of epsilon would be good, including these:
GC> $grep 'epsilon_plus_one\|ldbl_eps_plus_one' *.?pp
GC> which have the same rationale as described above.
I've added a task for this: https://github.com/vadz/lmi/issues/22
GC> More idealistically, we should probably use integral cents as our basic
GC> currency unit instead of floating-point dollars rounded to the closest
GC> approximation to integral hundredths, because in the real world we can
GC> have exactly seven cents, and (double)(0.07) is not exactly the same.
Yes, currency amounts are a classic example of things not to use floating
point numbers for. I guess there must have been some reasons
(compatibility?) to do it at some time, but it would be clearly better to
avoid it if possible. Please let me know if I should make an issue for this
too.
Thanks,
VZ
[lmi] Numerics [Was: Converting numbers in mortality tables to and from text], Greg Chicares, 2016/03/24