This library provides equality operators lhs = rhs
for many of the data
structures. The savvy among you may have noticed that all the data structures
are also storing float numbers. Comparing floating point equality is no easy
task. Due to floating point rounding errors when numbers are being stored, and
with many calculations (especially trig functions), the output numbers may be
slightly different than you would expect.
We can show this with an example. We would expect the following to be true
1. = (0.3 * 3.) + 0.1
Checking the returned value from the right hand side we see that we are getting
the value 1.0
. So what's going on?
(0.3 * 3.) + 0.1
Well, with a little investigation, we can see that we aren't getting exactly
1.0
. We are getting ever so slightly less than 1.0
.
((0.3 * 3.) + 0.1) - 1.
Comparing datastructures that use floating point numbers can sometimes be a sign
of bad code code design, but this is not always the case. So when you are
looking to do equality comparison, this library provides the ability to do
approximate equality comparison on floating point numbers and data structures
like points and vectors.
Float.almostEqual 1. ((0.3 * 3.) + 0.1)
You can change the precision that floating point operations are performed at. The
default precision is a digit precision of 10. If we were looking a higher level
of precision, you can change the digit precision to be something more fitting of
your needs. In this example, we can make that equality check fail by increasing
the precision we are requiring for this operation.
// Increasing the equality precision to make this check fail
Float.DigitPrecision <- 17
Float.almostEqual 1. ((0.3 * 3.) + 0.1)
namespace Math
namespace Math.Units
Multiple items
union case Cartesian.Cartesian: Cartesian
--------------------
type Cartesian = | Cartesian
Multiple items
module Float
from Math.Units
<category>Other</category>
--------------------
type Float =
static member DigitPrecision: int
static member Epsilon: float
static member MinNormal: float
<category>Other</category>
<summary>
A static class providing added features to the floating point number class.
</summary>
<remark><para>
A static class providing added features to the floating point number class.
The main features of this class allow for better floating point equality
testing. Generally, floating points always have small variations in their
values because the way that floating point numbers are encoded. It is often
useful to do equality comparison checks between floating point numbers in a
variety of contexts. There are two main ways of doing this type of
comparison. The first is to use a percentage tolerance between two numbers,
eg. Two floating point numbers are equal if they are within 0.01% of each
other. Another is to compare if the two numbers are within an absolute range
from each other, eg. Two floating point numbers are equal if they are within
0.0001 units of each other.
</para><para>
This library does comparison by absolute value comparison through digit
precision. Numbers are considered equal if they are equal when rounded to
the number of digits as specified by <c>Float.DigitPrecision</c>.
The default is 10 digits, so by default <c>2.0 = 2.00000000003</c> (the 11th digit is a 3).
</para><para><c>Float.Epsilon</c> is a derived value from the number of digits and represents
the maximum difference between two numbers that is considered equal. This
number is <c>10^-(DigitPrecision)</c> which by default is <c>10^(-10)</c>, or
<c>0.000000001</c>.
</para><para>
In general the rules followed by this extension are from
<a href="https://floating-point-gui.de/errors/comparison/">The Floating Point Guide on Comparison</a></para></remark>
val almostEqual: a: float -> b: float -> bool
<summary>
Compare two floating point values for equality. Equality testing is done
based on a tolerance vale specified by <c>Float.Epsilon</c>.
</summary>
property Float.DigitPrecision: int with get, set
<summary>
The number of digits (in base 10) that are used for approximate equality tests.
</summary>