[Cuis-dev] testing Float results
Mark Volkmann
r.mark.volkmann at gmail.com
Tue Jun 4 13:31:33 PDT 2024
Excellent feedback Andres!
For my simple use case (really just trying to learn how to implement unit
tests in Smalltalk), I changed the code to the following and it works:
testCircleArea
"tests the VCircle area method"
| c |
c := VCircle radius: 3.
self assert: c area isCloseTo: 28.274333882308138 withPrecision: 1e-15
I'm very new to Smalltalk and always open to feedback!
On Tue, Jun 4, 2024 at 3:13 PM Andres Valloud via Cuis-dev <
cuis-dev at lists.cuis.st> wrote:
> I think checking for a relative error on the order of 10^-4 when double
> precision floating point numbers can represent relative errors on the
> order of 10^-16 is not good. This means that the result can be off by a
> factor of roughly 10^12 and still be "correct".
>
> Moreover, the implementation is incorrect because if the numbers being
> compared are denormals, multiplying by 0.0001 will lead to things like
>
> nonZero < 0.0
>
> in the code, which always fails.
>
> For example,
>
> good := 10 raisedTo: 16.
> bad := good + (10 raisedTo: 12).
> [
> TestCase new assert: good asFloat isCloseTo: bad asFloat.
> #allGood
> ] on: TestFailure do: [:ex | ex return: #allWrong]
>
> returns #allGood (but the relative error is huge!). Meanwhile,
>
> good := 10 raisedTo: 16.
> bad := good + (10 raisedTo: 13).
> [
> TestCase new assert: good asFloat isCloseTo: bad asFloat.
> #allGood
> ] on: TestFailure do: [:ex | ex return: #allWrong]
>
> returns #allWrong because apparently the results are unacceptable after
> losing more than ~75% of the precision available. Finally,
>
> good := Float fminDenormalized * 10.
> bad := good.
> [
> TestCase new assert: good asFloat isCloseTo: bad asFloat.
> #allGood
> ] on: TestFailure do: [:ex | ex return: #allWrong]
>
> returns #allWrong even though good = bad.
>
> This kind of relative error checking makes sense, of course, but only
> when you do substantial numerical analysis homework to know what the
> tolerable threshold actually is for the application at hand. In
> practice this is not done, and arbitrary statements like "0.0001
> relative error is good enough for everyone" effectively suppress
> curiosity into how things actually work. On top of that, this threshold
> is so lax that it hides basically all but the most egregious errors
> under the rug.
>
> Intel got into a lot of trouble over its Pentium FDIV bug for errors
> much smaller than this. The x87 FPU had trigonometric transcendental
> instructions that were grossly imprecise in certain cases (e.g. only
> about 15 bits of the 53 bit mantissa made sense and the rest were
> rubbish) because of poor argument reduction. The modern x86 CPU vector
> units do not have hardware transcendental support because you can use
> SSE to implement great precision trigonometry with far less effort than
> you can do that in hardware, and in addition the process is very fast.
> These are the types of problems you ignore when you say things like
> "it's within 10^-4", and obviously this is contrary to understanding,
> personal mastery, and so on.
>
> So instead of that, I would ensure that the actual result is a certain,
> well understood number of ulps of the expected value. The ulp tolerance
> depends on the numerical analysis for the calculations being done. If
> you do not do this, then you constantly run the risk of living in the
> world of the Indiana pi bill.
>
> https://en.wikipedia.org/wiki/Indiana_pi_bill
>
> There is no royal road to floating point arithmetic.
>
> On 6/4/24 12:06 PM, Mark Volkmann via Cuis-dev wrote:
> > How do you feel about using "approximately equal" tests for things like
> > unit tests for the calculation of areas of 2D shapes such as circles?
> >
> > On Mon, Jun 3, 2024 at 10:47 PM Martin McClure via Cuis-dev
> > <cuis-dev at lists.cuis.st <mailto:cuis-dev at lists.cuis.st>> wrote:
> >
> > Hi Mark,
> >
> > Welcome to the list -- good to see you diving into Cuis!
> >
> > As Andres says, there are messages to do this kind of test on Floats.
> >
> > I find myself compelled, however, to warn about using such
> > "approximately equal" tests when inappropriate. I recently discovered
> > this kind of usage in an ancient test framework, and it was allowing
> > tests to pass that should not have. Those tests are being replaced
> with
> > equality tests.
> >
> > As I commented to a co-worker just this morning, accepting as
> correct a
> > Float result that is one ULP different from the correct Float is
> really
> > no different than accepting 5 as a correct answer to 2 + 2.
> >
> > There are, of course, times when figuring out the exact rounding
> > expected in a sequence of floating-point operations is impractical,
> and
> > accepting a certain amount of cumulative error is OK. Floats are
> often
> > used in applications where accuracy is only required to some specific
> > precision, but it's also good to keep in mind that each Float
> precisely
> > represents one value, and each operation on a Float has only one
> > correct
> > answer.
> >
> > Regards,
> > -Martin
> >
> > On 6/3/24 19:49, Andres Valloud via Cuis-dev wrote:
> > > Look at Float>>isWithin:floatsFrom:, and see also Float>>ulp.
> > >
> > > On 6/3/24 4:36 PM, Mark Volkmann via Cuis-dev wrote:
> > >> Is there a function that tests whether two Float values are
> "close"
> > >> (within some delta)?
> > >> I can write it, but I thought that might be provided.
> > >> I looked at all the methods in the Float class, but didn't find
> one
> > >> like that.
> > >>
> > >> --
> > >> R. Mark Volkmann
> > >> Object Computing, Inc.
> > >>
> >
> > --
> > Cuis-dev mailing list
> > Cuis-dev at lists.cuis.st <mailto:Cuis-dev at lists.cuis.st>
> > https://lists.cuis.st/mailman/listinfo/cuis-dev
> > <https://lists.cuis.st/mailman/listinfo/cuis-dev>
> >
> >
> >
> > --
> > R. Mark Volkmann
> > Object Computing, Inc.
> >
> --
> Cuis-dev mailing list
> Cuis-dev at lists.cuis.st
> https://lists.cuis.st/mailman/listinfo/cuis-dev
>
--
R. Mark Volkmann
Object Computing, Inc.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.cuis.st/mailman/archives/cuis-dev/attachments/20240604/d3831782/attachment.htm>
More information about the Cuis-dev
mailing list