Approximate equality: Difference between revisions
m
→{{header|Wren}}: Changed to Wren S/H
m (→{{header|Wren}}: Changed to Wren S/H) |
|||
(35 intermediate revisions by 16 users not shown) | |||
Line 34:
=={{header|Ada}}==
<syntaxhighlight lang="ada">
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Numerics.Generic_Elementary_Functions;
Line 81:
end Main;
</syntaxhighlight>
{{Output}}
<pre>
Line 92:
-2.0000000000000000 -2.0000000000000000 FALSE
3.1415926535897932 3.1415926535897932 TRUE
</pre>
=={{header|ALGOL 68}}==
{{Trans|Kotlin}}
<syntaxhighlight lang="algol68">BEGIN # test REAL values for approximate equality #
# returns TRUE if value is approximately equal to other, FALSE otherwide #
PROC approx equals = ( REAL value, REAL other, REAL epsilon )BOOL: ABS ( value - other ) < epsilon;
# shows the result of testing a for approximate equality with b #
PROC test = ( REAL a, b )VOID:
BEGIN
REAL epsilon = 1e-18;
print( ( a, ", ", b, " => ", IF approx equals( a, b, epsilon ) THEN "true" ELSE "false" FI, newline ) )
END # test # ;
# task test cases #
test( 100000000000000.01, 100000000000000.011 );
test( 100.01, 100.011 );
test( 10000000000000.001 / 10000.0, 1000000000.0000001000);
test( 0.001, 0.0010000001 );
test( 0.000000000000000000000101, 0.0 );
test( sqrt( 2 ) * sqrt( 2 ), 2.0 );
test( - sqrt( 2 ) * sqrt( 2 ), -2.0 );
test( 3.14159265358979323846, 3.14159265358979324 )
END</syntaxhighlight>
{{out}}
<pre>
+1.00000000000000e +14, +1.00000000000000e +14 => true
+1.00010000000000e +2, +1.00011000000000e +2 => false
+1.00000000000000e +9, +1.00000000000000e +9 => false
+1.00000000000000e -3, +1.00000010000000e -3 => false
+1.01000000000000e -22, +0.00000000000000e +0 => true
+2.00000000000000e +0, +2.00000000000000e +0 => false
-2.00000000000000e +0, -2.00000000000000e +0 => false
+3.14159265358979e +0, +3.14159265358979e +0 => true
</pre>
=={{header|AWK}}==
<syntaxhighlight lang="awk">
# syntax: GAWK -f APPROXIMATE_EQUALITY.AWK
# converted from C#
Line 119 ⟶ 152:
}
function abs(x) { if (x >= 0) { return x } else { return -x } }
</syntaxhighlight>
{{out}}
<pre>
Line 136 ⟶ 169:
=={{header|C}}==
{{trans|Java}}
<
#include <stdbool.h>
#include <stdio.h>
Line 159 ⟶ 192:
test(3.14159265358979323846, 3.14159265358979324);
return 0;
}</
{{out}}
<pre>100000000000000.015625, 100000000000000.015625 => 1
Line 171 ⟶ 204:
=={{header|C sharp|C#}}==
<
public static class Program
Line 192 ⟶ 225:
public static bool ApproxEquals(this double value, double other, double epsilon) => Math.Abs(value - other) < epsilon;
}</
{{out}}
<pre>
Line 206 ⟶ 239:
=={{header|C++}}==
{{trans|C}}
<
#include <iostream>
#include <cmath>
Line 233 ⟶ 266:
test(3.14159265358979323846, 3.14159265358979324);
return 0;
}</
{{out}}
<pre>100000000000000.015625, 100000000000000.015625 => 1
Line 243 ⟶ 276:
-2.00000000000000044409, -2 => 0
3.141592653589793116, 3.141592653589793116 => 1</pre>
=={{header|Common Lisp}}==
This solution compares the normalized (i.e. between 0.5 and 1 on implementations which use binary floating point) significands of the floating point numbers, correcting each significand by half the difference in the exponents so that the corrected numbers used for comparison have the same difference in order of magnitude as the original numbers and are stable when the order of the arguments is changed. Unlike the metric of comparing the difference to some fraction of the numbers' size, this approach only requires two floating point operations (the subtraction and comparison at the end), and more directly maps to the fundamental issue which leads to the need for floating-point comparisons, i.e. the limited precision of the significand.
<syntaxhighlight lang="lisp">
(defun approx-equal (float1 float2 &optional (threshold 0.000001))
"Determine whether float1 and float2 are equal; THRESHOLD is the
maximum allowable difference between normalized significands of floats
with the same exponent. The significands are scaled appropriately
before comparison for floats with different exponents."
(multiple-value-bind (sig1 exp1 sign1) (decode-float float1)
(multiple-value-bind (sig2 exp2 sign2) (decode-float float2)
(let ((cmp1 (float-sign sign1 (scale-float sig1 (floor (- exp1 exp2) 2))))
(cmp2 (float-sign sign2 (scale-float sig2 (floor (- exp2 exp1) 2)))))
(< (abs (- cmp1 cmp2)) threshold)))))
</syntaxhighlight>
=={{header|D}}==
{{trans|C#}}
<
import std.stdio;
Line 265 ⟶ 314:
test(-sqrt(2.0) * sqrt(2.0), -2.0);
test(3.14159265358979323846, 3.14159265358979324);
}</
{{out}}
<pre>100000000000000.015620000000000000, 100000000000000.015620000000000000 => true
Line 279 ⟶ 328:
{{libheader| System.Math}}
The Delphi has a Math.SameValue function for compare, but all float operations use by default Extended (High precision), we need use double cast for every operation, like division, multiply and square tree.
<syntaxhighlight lang="delphi">
program Approximate_Equality;
Line 315 ⟶ 364:
end.
</syntaxhighlight>
{{out}}
Line 332 ⟶ 381:
The <code>~</code> word takes three arguments: the two values to be compared, and an epsilon value representing the allowed distance between the two values. A positive epsilon performs an absolute distance test, an epsilon of zero performs an exact comparison, and a negative epsilon performs a relative distance test (as required by this task).
{{works with|Factor|0.99 development version 2019-07-10}}
<
100000000000000.01 100000000000000.011
Line 344 ⟶ 393:
[ 2dup -1e-15 ~ "%+47.30f %+47.30f -1e-15 ~ : %u\n" printf ]
2 8 mnapply</
{{out}}
<pre>
Line 355 ⟶ 404:
-2.000000000000000444089209850063 -2.000000000000000000000000000000 -1e-15 ~ : t
+3.141592653589793115997963468544 +3.141592653589793115997963468544 -1e-15 ~ : t
</pre>
=={{header|Forth}}==
{{works with|GForth | 0.7.9_20211014}}
Genuine Forth word :
f~ ( r1 r2 r3 – flag ) float-ext “f-proximate”
ANS Forth medley for comparing r1 and r2 for equality: r3>0: f~abs; r3=0: bitwise comparison; r3<0:
<syntaxhighlight lang="forth">
: test-f~ ( f1 f2 -- )
1e-18 \ epsilon
f~ \ AproximateEqual
if ." True" else ." False" then
;
</syntaxhighlight>
{{out}}
<pre>
100000000000000.01e 100000000000000.011e test-f~ True
100.01e 100.011e test-f~ False
10000000000000.001e 10000.0e f/ 1000000000.0000001000e test-f~ False
0.001e 0.0010000001e test-f~ False
0.000000000000000000000101e 0.0e test-f~ True
2.0e fdup fsqrt fswap fsqrt f* 2.0e test-f~ False
2.0e fdup fsqrt fnegate fswap fsqrt f* -2.0e test-f~ False
3.14159265358979323846e 3.14159265358979324e test-f~ True
</pre>
Line 360 ⟶ 433:
Compare against the Python function documented at https://www.python.org/dev/peps/pep-0485/#proposed-implementation,
and with the discussion at https://stackoverflow.com/questions/5595425/what-is-the-best-way-to-compare-floats-for-almost-equality-in-python#
<
implicit none
Line 401 ⟶ 474:
end function
end program</
{{out}}
<pre> 1.000000000000000156E+14 == 1.000000000000000156E+14 ? T
Line 415 ⟶ 488:
=={{header|FreeBASIC}}==
{{trans|AWK}}
<
Dim Shared As Double epsilon = 1
Line 439 ⟶ 512:
eq_approx(3.14159265358979323846, 3.14159265358979324)
Sleep</
=={{header|FutureBasic}}==
<syntaxhighlight lang="futurebasic">
local fn DoublesAreApproxEqual( val1 as double, val2 as double, epsilon as double ) as CFStringRef
CFStringRef result = @"false"
if ( fn fabs( val1 - val2 ) < epsilon ) then result = @"true"
end fn = result
void local fn DoIt
long i
double epsilon = 1e-18, values(15)
values(0) = 100000000000000.01 : values(1) = 100000000000000.011
values(2) = 100.01 : values(3) = 100.011
values(4) = 10000000000000.001 / 10000.0 : values(5) = 1000000000.0000001000
values(6) = 0.001 : values(7) = 0.0010000001
values(8) = 0.000000000000000000000101 : values(9) = 0.0
values(10) = fn sqrt(2) * fn sqrt(2) : values(11) = 2.0
values(12) = -fn sqrt(2) * fn sqrt(2) : values(13) = -2.0
values(14) = 3.14159265358979323846 : values(15) = 3.14159265358979324
for i = 0 to 14 step 2
print values(i)@", "values(i+1)@" "fn DoublesAreApproxEqual( values(i), values(i+1), epsilon )
next
end fn
fn DoIt
HandleEvents
</syntaxhighlight>
{{out}}
<pre>
100000000000000, 100000000000000 true
100.01, 100.011 false
1000000000, 1000000000 false
0.001, 0.0010000001 false
1.01e-22, 0 true
2, 2 false
-2, -2 false
3.141592653589793, 3.141592653589793 true
</pre>
=={{header|Go}}==
Go's float64 type is limited to 15 or 16 digits of precision. As there are some numbers in this task which have more digits than this I've used big.Float instead.
<
import (
Line 498 ⟶ 612:
fmt.Printf("% 21.19g %s %- 21.19g\n", pair[0], s, pair[1])
}
}</
{{out}}
Line 515 ⟶ 629:
=={{header|Groovy}}==
{{trans|Java}}
<
private static boolean approxEquals(double value, double other, double epsilon) {
return Math.abs(value - other) < epsilon
Line 535 ⟶ 649:
test(3.14159265358979323846, 3.14159265358979324)
}
}</
{{out}}
<pre>100000000000000.020000, 100000000000000.020000 => true
Line 545 ⟶ 659:
-2.000000, -2.000000 => false
3.141593, 3.141593 => true</pre>
=={{header|Haskell}}==
<syntaxhighlight lang="haskell">class (Num a, Ord a, Eq a) => AlmostEq a where
eps :: a
infix 4 ~=
(~=) :: AlmostEq a => a -> a -> Bool
a ~= b = or [ a == b
, abs (a - b) < eps * abs(a + b)
, abs (a - b) < eps ]
instance AlmostEq Int where eps = 0
instance AlmostEq Integer where eps = 0
instance AlmostEq Double where eps = 1e-14
instance AlmostEq Float where eps = 1e-5</syntaxhighlight>
Examples
<pre>λ> 0.000001 == (0 :: Float)
False
λ> 0.000001 ~= (0 :: Float)
True
λ> 0.000001 ~= (0 :: Double)
False
λ> (\x -> sqrt x * sqrt x == x) $ (2 :: Float)
False
λ> (\x -> sqrt x * sqrt x ~= x) $ (2 :: Float)
True
λ> (\x -> sqrt x * sqrt x == x) $ (2 :: Double)
False
λ> (\x -> sqrt x * sqrt x ~= x) $ (2 :: Double)
True</pre>
Assignment
<syntaxhighlight lang="haskell">test :: [(Double, Double)]
test = [(100000000000000.01, 100000000000000.011)
,(100.01, 100.011)
,(10000000000000.001 / 10000.0, 1000000000.0000001000)
,(0.001, 0.0010000001)
,(0.000000000000000000000101, 0.0)
,(sqrt 2 * sqrt 2, 2.0)
,(-sqrt 2 * sqrt 2, -2.0)
,(3.141592653589793, 3.141592653589794)
,(3.141592653589, 3.141592653589794)]
-- requires import Text.Printf
main = mapM_ runTest test
where
runTest (a, b) = do
printf "%f == %f %v\n" a b (show $ a==b) :: IO ()
printf "%f ~= %f %v\n\n" a b (show $ a~=b)</syntaxhighlight>
<pre>λ> main
100000000000000.02 == 100000000000000.02 True
100000000000000.02 ~= 100000000000000.02 True
100.01 == 100.011 False
100.01 ~= 100.011 False
1000000000.0000002 == 1000000000.0000001 False
1000000000.0000002 ~= 1000000000.0000001 True
0.001 == 0.0010000001 False
0.001 ~= 0.0010000001 False
0.000000000000000000000101 == 0.0 False
0.000000000000000000000101 ~= 0.0 True
2.0000000000000004 == 2.0 False
2.0000000000000004 ~= 2.0 True
-2.0000000000000004 == -2.0 False
-2.0000000000000004 ~= -2.0 True
3.141592653589793 == 3.141592653589794 False
3.141592653589793 ~= 3.141592653589794 True
3.141592653589 == 3.141592653589794 False
3.141592653589 ~= 3.141592653589794 False</pre>
=={{header|J}}==
Line 551 ⟶ 746:
J includes a "customization" conjunction ( !. ) that delivers variants of some verbs. Comparisons are tolerant by default, and their tolerance can be customized to some level. Specifying =!.0 specifies "no tolerance". Specifying a tolerance of 1e_8 is a domain error because that's no longer math. Write your own verb if you need this.
<syntaxhighlight lang="text">
NB. default comparison tolerance matches the python result
".;._2]0 :0
Line 596 ⟶ 791:
|domain error
| 2(= !.1e_8)9
</syntaxhighlight>
=={{header|Java}}==
{{trans|Kotlin}}
<
private static boolean approxEquals(double value, double other, double epsilon) {
return Math.abs(value - other) < epsilon;
Line 620 ⟶ 815:
test(3.14159265358979323846, 3.14159265358979324);
}
}</
{{out}}
<pre>100000000000000.020000, 100000000000000.020000 => true
Line 630 ⟶ 825:
-2.000000, -2.000000 => false
3.141593, 3.141593 => true</pre>
=={{header|jq}}==
{{trans|Lobster}}
<syntaxhighlight lang="jq"># Return whether the two numbers `a` and `b` are close.
# Closeness is determined by the `epsilon` parameter -
# the numbers are considered close if the difference between them
# is no more than epsilon * max(abs(a), abs(b)).
def isclose(a; b; epsilon):
((a - b) | fabs) <= (([(a|fabs), (b|fabs)] | max) * epsilon);
def lpad($len; $fill): tostring | ($len - length) as $l | ($fill * $l)[:$l] + .;
def lpad: lpad(20; " ");
# test values
def tv: [
{x: 100000000000000.01, y: 100000000000000.011 },
{x: 100.01, y: 100.011 },
{x: (10000000000000.001 / 10000.0), y: 1000000000.0000001000 },
{x: 0.001, y: 0.0010000001 },
{x: 0.000000000000000000000101, y: 0.0 },
{x: ((2|sqrt) * (2|sqrt)), y: 2.0 },
{x: (-(2|sqrt) * (2|sqrt)), y: -2.0 },
{x: 3.14159265358979323846, y: 3.14159265358979324 }
]
;
tv[] | "\(.x|lpad) \(if isclose(.x; .y; 1.0e-9) then " ≈ " else " ≉ " end) \(.y|lpad)"
</syntaxhighlight>
{{out}}
Using jq 1.6:
<syntaxhighlight lang="sh"> 100000000000000.02 ≈ 100000000000000.02
100.01 ≉ 100.011
1000000000.0000002 ≈ 1000000000.0000001
0.001 ≉ 0.0010000001
1.01e-22 ≉ 0
2.0000000000000004 ≈ 2
-2.0000000000000004 ≈ -2
3.141592653589793 ≈ 3.141592653589793</syntaxhighlight>
=={{header|Julia}}==
Julia has an infix operator, ≈, which corresponds to Julia's buitin isapprox() function.
{{trans|Python}}
<
[100.01, 100.011],
[10000000000000.001 / 10000.0, 1000000000.0000001000],
Line 646 ⟶ 880:
println(rpad(x, 21), " ≈ ", lpad(y, 22), ": ", x ≈ y)
end
</
<pre>
1.0000000000000002e14 ≈ 1.0000000000000002e14: true
Line 660 ⟶ 894:
=={{header|Kotlin}}==
{{trans|C#}}
<
import kotlin.math.sqrt
Line 681 ⟶ 915:
test(-sqrt(2.0) * sqrt(2.0), -2.0)
test(3.14159265358979323846, 3.14159265358979324)
}</
{{out}}
<pre>1.0000000000000002E14, 1.0000000000000002E14 => true
Line 694 ⟶ 928:
=={{header|Lobster}}==
{{trans|Rust}}
<syntaxhighlight lang="lobster">
// Return whether the two numbers `a` and `b` are close.
// Closeness is determined by the `epsilon` parameter -
Line 716 ⟶ 950:
for(tv) t:
print concat_string([string(t.x), if isclose(t.x, t.y, 1.0e-9): """ ≈ """ else: """ ≉ """, string(t.y)], "")
</syntaxhighlight>
{{out}}
<pre>
Line 731 ⟶ 965:
=={{header|Lua}}==
{{trans|C}}
<
return math.abs(value - other) < epsilon
end
Line 751 ⟶ 985:
end
main()</
{{out}}
<pre>100000000000000.020000, 100000000000000.020000 => true
Line 761 ⟶ 995:
-2.000000, -2.000000 => false
3.141593, 3.141593 => true</pre>
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<syntaxhighlight lang="mathematica">ClearAll[CloseEnough]
CloseEnough[a_, b_, tol_] := Chop[a - b, tol] == 0
numbers = {
{100000000000000.01, 100000000000000.011},
{100.01, 100.011},
{10000000000000.001/10000.0, 1000000000.0000001000},
{0.001, 0.0010000001},
{0.000000000000000000000101, 0.0},
{Sqrt[2.0] Sqrt[2.0], 2.0}, {-Sqrt[2.0] Sqrt[2.0], -2.0},
{3.14159265358979323846, 3.14159265358979324}
};
(*And@@Flatten[Map[MachineNumberQ,numbers,{2}]]*)
{#1, #2, CloseEnough[#1, #2, 10^-9]} & @@@ numbers // Grid</syntaxhighlight>
{{out}}
<pre>1.*10^14 1.0000000000000001*10^14 True
100.01 100.011 False
1.*10^9 1.000000000000000100*10^9 False
0.001 0.001 True
1.01*10^-22 0. True
2. 2. True
-2. -2. True
3.1415926535897932385 3.1415926535897932 True</pre>
=={{header|Nim}}==
Line 767 ⟶ 1,025:
In order to display the values “a” and “b” as provided, without any rounding, we transmit them as strings to a comparison procedure which compute the floating point values. If the first value “a” is provided as an operation, we use a comparison procedure which accepts the computed value of “a” as second parameter. Here, “b” is never provided as an operation and can always be transmitted as a string.
<
import strformat
import strutils
Line 798 ⟶ 1,056:
compare("sqrt(2) * sqrt(2)", sqrt(2.0) * sqrt(2.0), "2.0")
compare("-sqrt(2) * sqrt(2)", -sqrt(2.0) * sqrt(2.0), "-2.0")
compare("3.14159265358979323846", "3.14159265358979324")</
{{out}}
Line 809 ⟶ 1,067:
-sqrt(2) * sqrt(2) ~= -2.0 is true
3.14159265358979323846 ~= 3.14159265358979324 is true</pre>
=={{header|OCaml}}==
<syntaxhighlight lang="ocaml">let approx_eq v1 v2 epsilon =
Float.abs (v1 -. v2) < epsilon
let test a b =
let epsilon = 1e-18 in
Printf.printf "%g, %g => %b\n" a b (approx_eq a b epsilon)
let () =
test 100000000000000.01 100000000000000.011;
test 100.01 100.011;
test (10000000000000.001 /. 10000.0) 1000000000.0000001000;
test 0.001 0.0010000001;
test 0.000000000000000000000101 0.0;
test ((sqrt 2.0) *. (sqrt 2.0)) 2.0;
test (-. (sqrt 2.0) *. (sqrt 2.0)) (-2.0);
test 3.14159265358979323846 3.14159265358979324;
;;
</syntaxhighlight>
=={{header|Pascal}}==
{{works with|Extended Pascal}}
The constants <tt>minReal</tt>, <tt>maxReal</tt> and <tt>epsReal</tt> are defined by the ISO standard 10206 (“Extended Pascal”).
However, their specific values are “implementation defined”, i. e. it is up to the compiler vendors to assign concrete values to them.
<syntaxhighlight lang="pascal">program approximateEqual(output);
{
\brief determines whether two `real` values are approximately equal
\param x a reference value
\param y the value to compare with \param x
\return true if \param x is equal or approximately equal to \param y
}
function equal(protected x, y: real): Boolean;
function approximate: Boolean;
function d(protected x: real): integer;
begin
d := trunc(ln(abs(x) + minReal) / ln(2)) + 1
end;
begin
approximate := abs(x - y) <= epsReal * (maxReal / (d(x) + d(y)))
end;
begin
equal := (x = y) or_else (x * y >= 0.0) and_then approximate
end;
{ --- auxilliary routines ---------------------------------------------- }
procedure test(protected x, y: real);
const
{ ANSI escape code for color coding }
CSI = chr(8#33) + '[';
totalMinimumWidth = 40;
postRadixDigits = 24;
begin
write(x:totalMinimumWidth:postRadixDigits, '':1, CSI, '1;3');
if equal(x, y) then
begin
if x = y then
begin
write('2m≅')
end
else
begin
write('5m≆')
end
end
else
begin
write('1m≇')
end;
writeLn(CSI, 'm', '':1, y:totalMinimumWidth:postRadixDigits)
end;
{ === MAIN ============================================================= }
var
n: integer;
x: real;
begin
{ Variables were used to thwart compile-time evaluation done }
{ by /some/ compilers potentially confounding the results. }
n := 2;
x := 100000000000000.01;
test(x, 100000000000000.011);
test(100.01, 100.011);
test(x / 10000.0, 1000000000.0000001000);
test(0.001, 0.0010000001);
test(0.000000000000000000000101, 0.0);
x := sqrt(n);
test(sqr(x), 2.0);
test((-x) * x, -2.0);
test(3.14159265358979323846, 3.14159265358979324)
end.</syntaxhighlight>
{{out}}
100000000000000.015625000000000000000000 ≅ 100000000000000.015625000000000000000000
100.010000000000005115907697 ≆ 100.010999999999995679900167
10000000000.000001907348632812500000 ≆ 1000000000.000000119209289550781250
0.001000000000000000020817 ≇ 0.001000000100000000054917
0.000000000000000000000101 ≇ 0.000000000000000000000000
2.000000000000000444089210 ≆ 2.000000000000000000000000
-2.000000000000000444089210 ≆ -2.000000000000000000000000
3.141592653589793115997963 ≅ 3.141592653589793115997963
The shown output was generated by a <tt>program</tt> compiled by the GPC (GNU Pascal Compiler).
Due to technical limitations it was not possible to reproduce 100.01 ≆ 100.011 as requested by the task specification.
The computer had an IEEE-754-compliant FPU with 80-bit precision.
Note that Pascal’s <tt>write</tt>/<tt>writeLn</tt>/<tt>writeStr</tt> routines (the last one is only available in Extended Pascal) produce ''rounded'' representations.
=={{header|Perl}}==
Passes task tests, but use the module <code>Test::Number::Delta</code> for anything of real importance.
<
use warnings;
Line 844 ⟶ 1,210:
my $real_pi = 2 * atan2(1, 0);
my $roman_pi = 22/7;
is_close($real_pi,$roman_pi,$_) for <10 3>;</
{{out}}
<pre>True 100000000000000.0 ≅ 100000000000000.0
Line 862 ⟶ 1,228:
=={{header|Phix}}==
Traditionally I have always just used sprintf() to compare floating point atoms in phix.<br>
This task (imo) is trying to make a general-purpose routine out of code
It proved much harder to get decent-looking output than perform the tests, hence I allowed both the compare (cfmt) and display (dfmt) formats to be overridden.<br>
I got a different result for test 4 to everyone else, but simply setting the cfmt to "%.
Likewise something similar for the trickier/ambiguous test 5, for which "0.000000" is as good as anything I can do, and both now show how to get either a true or false result.
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">test</span><span style="color: #0000FF;">(</span><span style="color: #004080;">atom</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">,</span><span style="color: #000000;">b</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">string</span> <span style="color: #000000;">dfmt</span><span style="color: #0000FF;">=</span><span style="color: #008000;">"%g"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">cfmt</span><span style="color: #0000FF;">=</span><span style="color: #008000;">"%g"</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">ca</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cfmt</span><span style="color: #0000FF;">,</span><span style="color: #000000;">a</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">cb</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cfmt</span><span style="color: #0000FF;">,</span><span style="color: #000000;">b</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">eqs</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ca</span><span style="color: #0000FF;">=</span><span style="color: #000000;">cb</span><span style="color: #0000FF;">?</span><span style="color: #008000;">""</span><span style="color: #0000FF;">:</span><span style="color: #008000;">"NOT "</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">da</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">dfmt</span><span style="color: #0000FF;">,</span><span style="color: #000000;">a</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">db</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">dfmt</span><span style="color: #0000FF;">,</span><span style="color: #000000;">b</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%30s and\n%30s are %sapproximately equal\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">da</span><span style="color: #0000FF;">,</span><span style="color: #000000;">db</span><span style="color: #0000FF;">,</span><span style="color: #000000;">eqs</span><span style="color: #0000FF;">})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #000000;">test</span><span style="color: #0000FF;">(</span><span style="color: #000000;">100000000000000.01</span><span style="color: #0000FF;">,</span><span style="color: #000000;">100000000000000.011</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%.3f"</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">test</span><span style="color: #0000FF;">(</span><span style="color: #000000;">100.01</span><span style="color: #0000FF;">,</span><span style="color: #000000;">100.011</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%.3f"</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">test</span><span style="color: #0000FF;">(</span><span style="color: #000000;">10000000000000.001</span><span style="color: #0000FF;">/</span><span style="color: #000000;">10000.0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1000000000.0000001000</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%.10f"</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">test</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0.001</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0.0010000001</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%.10f"</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- both</span>
<span style="color: #000000;">test</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0.001</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0.0010000001</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%.10f"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%.10f"</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- ways</span>
<span style="color: #000000;">test</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0.000000000000000000000101</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0.0</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%f"</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- both</span>
<span style="color: #000000;">test</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0.000000000000000000000101</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0.0</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%f"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%6f"</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- ways</span>
<span style="color: #000000;">test</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">sqrt</span><span style="color: #0000FF;">(</span><span style="color: #000000;">2</span><span style="color: #0000FF;">)*</span><span style="color: #7060A8;">sqrt</span><span style="color: #0000FF;">(</span><span style="color: #000000;">2</span><span style="color: #0000FF;">),</span><span style="color: #000000;">2.0</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">test</span><span style="color: #0000FF;">(-</span><span style="color: #7060A8;">sqrt</span><span style="color: #0000FF;">(</span><span style="color: #000000;">2</span><span style="color: #0000FF;">)*</span><span style="color: #7060A8;">sqrt</span><span style="color: #0000FF;">(</span><span style="color: #000000;">2</span><span style="color: #0000FF;">),-</span><span style="color: #000000;">2.0</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">test</span><span style="color: #0000FF;">(</span><span style="color: #000000;">3.14159265358979323846</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3.14159265358979324</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%.20f"</span><span style="color: #0000FF;">)</span>
<!--</syntaxhighlight>-->
{{out}}
64 bit (implied by some of the accuracies specified for this task):
<pre>
100000000000000.010
100.010 and
1000000000.0000001001 and
1000000000.0000001000 are approximately equal
0.0010000000 and
0.0010000001
0.0010000000
0.0010000001 are NOT approximately equal
0.000000 and
0.000000 are NOT approximately equal
0.000000 and
0.000000 are approximately equal
2 and
2 are approximately equal
-2 and
-2 are approximately equal
3.14159265358979323851 and
3.14159265358979324003 are approximately equal
</pre>
32 bit (in fact a couple of them, the first and last pairs, are actually genuinely identical):
<pre>
100000000000000.016
100.010 and
1000000000.0000002384 and
1000000000.0000001192 are approximately equal
0.0010000000 and
0.0010000001
0.0010000000
0.0010000001 are NOT approximately equal
0.000000 and
0.000000 are NOT approximately equal
0.000000 and
0.000000 are approximately equal
2 and
2 are approximately equal
-2 and
-2 are approximately equal
3.1415926535897931 and
3.1415926535897931 are approximately equal
</pre>
=={{header|Processing}}==
<syntaxhighlight lang="processing">double epsilon = 1e-18D;
void setup() {
testIsClose(100000000000000.01D, 100000000000000.011D, epsilon);
testIsClose(100.01D, 100.011D, epsilon);
testIsClose(10000000000000.001D / 10000.0D, 1000000000.0000001000D, epsilon);
testIsClose(0.001D, 0.0010000001D, epsilon);
testIsClose(0.000000000000000000000101D, 0.0D, epsilon);
testIsClose(Math.sqrt(2) * Math.sqrt(2), 2.0D, epsilon);
testIsClose(-Math.sqrt(2) * Math.sqrt(2), -2.0D, epsilon);
testIsClose(3.14159265358979323846D, 3.14159265358979324D, epsilon);
exit(); // all done
}
boolean isClose(double num1, double num2, double epsilon) {
return Math.abs(num2 - num1) <= epsilon;
}
void testIsClose(double num1, double num2, double epsilon) {
boolean result = isClose(num1, num2, epsilon);
if (result) {
println("True. ", num1, "is close to", num2);
} else {
println("False. ", num1, "is not close to", num2);
}
}</syntaxhighlight>
{{Output}}
<pre>
True. 1.0000000000000002E14 is close to 1.0000000000000002E14
False. 100.01 is not close to 100.011
False. 1.0000000000000002E9 is not close to 1.0000000000000001E9
False. 0.001 is not close to 0.0010000001
True. 1.01E-22 is close to 0.0
False. 2.0000000000000004 is not close to 2.0
False. -2.0000000000000004 is not close to -2.0
True. 3.141592653589793 is close to 3.141592653589793
</pre>
Line 933 ⟶ 1,365:
only close to themselves.
</pre>
<
from math import isclose
Line 949 ⟶ 1,381:
print(x, maybenot, "approximately equal to ", y)
</
<pre>
100000000000000.02 is approximately equal to 100000000000000.02
Line 960 ⟶ 1,392:
3.141592653589793 is approximately equal to 3.141592653589793
</pre>
=={{header|R}}==
The base library has the function all.equal() for this task. However, when the numbers are not equal, rather than return FALSE, it tries to explain the difference. To fix this, we use isTRUE(all.equal(....)) instead.
<syntaxhighlight lang="rsplus">approxEq <- function(...) isTRUE(all.equal(...))
tests <- rbind(c(100000000000000.01, 100000000000000.011),
c(100.01, 100.011),
c(10000000000000.001 / 10000.0, 1000000000.0000001000),
c(0.001, 0.0010000001),
c(0.000000000000000000000101, 0.0),
c(sqrt(2) * sqrt(2), 2.0),
c(-sqrt(2) * sqrt(2), -2.0),
c(3.14159265358979323846, 3.14159265358979324))
results <- mapply(approxEq, tests[, 1], tests[, 2])
#All that remains is to print out our results in a presentable way:
printableTests <- format(tests, scientific = FALSE)
print(data.frame(x = printableTests[, 1], y = printableTests[, 2], Equal = results, row.names = paste0("Test ", 1:8, ": ")))</syntaxhighlight>
{{out}}
<pre> x y Equal
Test 1: 100000000000000.015625000000000000000000 100000000000000.015625000000000000000000 TRUE
Test 2: 100.010000000000005115907697 100.010999999999995679900167 FALSE
Test 3: 1000000000.000000238418579101562500 1000000000.000000119209289550781250 TRUE
Test 4: 0.001000000000000000020817 0.001000000100000000054917 FALSE
Test 5: 0.000000000000000000000101 0.000000000000000000000000 TRUE
Test 6: 2.000000000000000444089210 2.000000000000000000000000 TRUE
Test 7: -2.000000000000000444089210 -2.000000000000000000000000 TRUE
Test 8: 3.141592653589793115997963 3.141592653589793115997963 TRUE</pre>
=={{header|Racket}}==
Line 965 ⟶ 1,422:
In Racket, a number literal with decimal point is considered a flonum, an inexact number which could be either 30 or 62 bits depending on machines. By prefixing the literal with <code>#e</code>, it is now considered an exact, rational number. In this task, we test the approximate equality on both variants:
<
(define (≈ a b [tolerance 1e-9])
Line 998 ⟶ 1,455:
(match-define (list a b) test)
(printf "~a ~a: ~a\n" (format-num a) (format-num b) (≈ a b)))
(newline))</
{{out}}
Line 1,034 ⟶ 1,491:
For example, in Raku, the sum of .1, .2, .3, & .4 is ''identically'' equal to 1.
<syntaxhighlight lang="raku"
It's also ''approximately'' equal to 1 but... ¯\_(ツ)_/¯
<syntaxhighlight lang="raku"
100000000000000.01, 100000000000000.011,
100.01, 100.011,
Line 1,059 ⟶ 1,516:
my $*TOLERANCE = .001;
say 22/7, " ≅ ", π, ": ", 22/7 ≅ π;
}</
{{out}}
<pre>100000000000000.01 ≅ 100000000000000.011: True
Line 1,074 ⟶ 1,531:
3.142857 ≅ 3.141592653589793: False
3.142857 ≅ 3.141592653589793: True</pre>
=={{header|ReScript}}==
<syntaxhighlight lang="rescript">let approx_eq = (v1, v2, epsilon) => {
abs_float (v1 -. v2) < epsilon
}
let test = (a, b) => {
let epsilon = 1e-18
Printf.printf("%g, %g => %b\n", a, b, approx_eq(a, b, epsilon))
}
{
test(100000000000000.01, 100000000000000.011)
test(100.01, 100.011)
test(10000000000000.001 /. 10000.0, 1000000000.0000001000)
test(0.001, 0.0010000001)
test(0.000000000000000000000101, 0.0)
test(sqrt(2.0) *. sqrt(2.0), 2.0)
test(-. sqrt(2.0) *. sqrt(2.0), (-2.0))
test(3.14159265358979323846, 3.14159265358979324)
}
</syntaxhighlight>
=={{header|REXX}}==
Line 1,080 ⟶ 1,559:
The choosing of the number of decimal digits is performed via the REXX statement: '''numeric digits ''nnn'' '''
<
numeric digits 15 /*what other FP hardware normally uses.*/
@.= /*assign default for the @ array. */
Line 1,109 ⟶ 1,588:
numeric form; m.=9; parse value format(x,2,1,,0) 'E0' with g "E" _ .; g=g *.5'e'_ %2
do j=0 while h>9; m.j=h; h=h%2+1; end /*j*/
do k=j+5 to 0 by -1; numeric digits m.k; g=(g+x/g)*.5; end /*k*/; return g/1</
{{out|output|text= when using the internal default inputs:}}
<pre>
Line 1,156 ⟶ 1,635:
B= 100000000000000004.0
A approximately equal to B? true
</pre>
=={{header|RPL}}==
We use here mantissa comparison, which makes that any epsilon can not be close to zero.
≪ MANT SWAP MANT - ABS 1E-09 <
≫ ‘'''CLOSE?'''’ STO
≪ {} { 100000000000000.01 100000000000000.011
100.01 100.011
≪ 10000000000000.001 10000 / ≫ 1000000000.0000001
0.001 0.0010000001
0.000000000000000000000101 0
≪ 2 √ 2 √ * ≫ 2
≪ 2 √ 2 √ * NEG ≫ -2
3.14159265358979323846, π }
1 OVER SIZE '''FOR''' j
DUP j GET EVAL OVER j 1 + GET EVAL '''CLOSE?'''
NUM→ "True" "False" IFTE ROT SWAP + SWAP 2 '''STEP'''
≫ ‘'''TASK'''’ STO
{{out}}
<pre>
1: { "True" "False" "True" "False" "False" "True" "True" "True" }
</pre>
=={{header|Ruby}}==
Most work went into handling weird Float values like NaN and Infinity.
<
testvalues = [[100000000000000.01, 100000000000000.011],
Line 1,187 ⟶ 1,688:
puts "#{a} #{a.close_to?(b) ? '≈' : '≉'} #{b}"
end
</syntaxhighlight>
{{out}}
<pre>100000000000000.02 ≈ 100000000000000.02
Line 1,202 ⟶ 1,703:
=={{header|Rust}}==
<
/// Closeness is determined by the `epsilon` parameter -
/// the numbers are considered close if the difference between them
Line 1,227 ⟶ 1,728:
test!(-sqrt(2.0) * sqrt(2.0), -2.0);
test!(3.14159265358979323846, 3.14159265358979324);
}</
{{out}}
<pre> 100000000000000.01 ≈ 100000000000000.011
Line 1,240 ⟶ 1,741:
{{Out}}Best seen running in your browser by [https://scastie.scala-lang.org/kxD9xQuIQEGpABXnsE6BiQ Scastie (remote JVM)].
<
val (ok, notOk, ε) = ("👌", "❌", 1e-18d)
Line 1,259 ⟶ 1,760:
test(BigDecimal(-Math.sqrt(2) * Math.sqrt(2)), BigDecimal(-2.0), false)
test(BigDecimal("3.14159265358979323846"), BigDecimal("3.14159265358979324"), true)
}</
=={{header|Sidef}}==
Two values can be compared for approximate equality by using the built-in operator '''≅''', available in ASCII as '''=~=''', which does approximate comparison by rounding both operands at '''(PREC>>2)-1''' decimals. However, by default, Sidef uses a floating-point precision of 192 bits.
<
100000000000000.01, 100000000000000.011,
100.01, 100.011,
Line 1,278 ⟶ 1,779:
].each_slice(2, {|a,b|
say ("#{a} ≅ #{b}: ", a ≅ b)
})</
{{out}}
<pre>
Line 1,297 ⟶ 1,798:
The Number '''n.round(-k)''' can be used for rounding the number ''n'' to ''k'' decimal places. A positive argument can be used for rounding before the decimal point.
<
var b = 100000000000000.011
# Rounding at 2 and 3 decimal places, respectively
say (round(a, -2) == round(b, -2)) # true
say (round(a, -3) == round(b, -3)) # false</
There is also the built-in '''approx_cmp(a, b, k)''' method, which is equivalent with '''a.round(k) <=> b.round(k)'''.
<
var b = Num.pi
say ("22/7 ≅ π at 2 decimals: ", approx_cmp(a, b, -2) == 0)
say ("22/7 ≅ π at 3 decimals: ", approx_cmp(a, b, -3) == 0)</
{{out}}
Line 1,320 ⟶ 1,821:
Additionally, the '''rat_approx''' method can be used for computing a very good rational approximation to a given real value:
<
say (zeta(-5).rat_approx == -1/252) # true</
Rational approximations illustrated for substrings of PI:
<
var r = Str(Num.pi).first(k)
say ("rat_approx(#{r}) = ", Num(r).rat_approx.as_frac)
}</
{{out}}
<pre>
Line 1,353 ⟶ 1,854:
There are slight differences in how this is named in the various dialects ¹. If required, you have to add a forwarding alias method to Number.
{{works with|Smalltalk/X}}
<
#(100.01 100.011) .
{10000000000000.001 / 10000.0 . 1000000000.0000001000} .
Line 1,363 ⟶ 1,864:
} pairsDo:[:val1 :val2 |
Stdout printCR: e'{val1} =~= {val2} -> {val1 isAlmostEqualTo:val2 nEpsilon:2}'
]</
In CUIS, this method is called <tt>isWithin:floatsFrom:</tt>.
{{out}}
Line 1,379 ⟶ 1,880:
Using the solution proposed as an addition to the Swift standard library in SE-0259. Currently this is not accepted, but is likely to be included in the Swift Numerics module.
<
extension FloatingPoint {
Line 1,446 ⟶ 1,947:
for testCase in testCases {
print("\(testCase.0), \(testCase.1) => \(testCase.0.isAlmostEqual(to: testCase.1))")
}</
{{out}}
Line 1,462 ⟶ 1,963:
===Using decimal library===
Uses tcllib's decimal library. Using a tolerance of 9 significant digits.
<
namespace eval test_almost_equal_decimal {
Line 1,497 ⟶ 1,998:
}
}
</
<pre>Is 100000000000000.01 ≈ 100000000000000.011 ? Yes.
Is 100.01 ≈ 100.011 ? No.
Line 1,509 ⟶ 2,010:
===Using string manipulation===
<
namespace eval test_almost_equal_string {
Line 1,552 ⟶ 2,053:
}
}
</syntaxhighlight>
{{out}}
<pre>Is 100000000000000.01 ≈ 100000000000000.011 ? Yes.
Line 1,566 ⟶ 2,067:
=={{header|Visual Basic .NET}}==
{{trans|C#}}
<
Module Module1
Line 1,591 ⟶ 2,092:
End Sub
End Module</
{{out}}
<pre>100000000000000, 100000000000000 => True
Line 1,603 ⟶ 2,104:
=={{header|Wren}}==
<
var pairs = [
[100000000000000.01, 100000000000000.011],
Line 1,619 ⟶ 2,120:
i = i + 1
System.print(" %(i) -> %((pair[0] - pair[1]).abs < tol)")
}</
{{out}}
Line 1,633 ⟶ 2,134:
8 -> true
</pre>
=={{header|XPL0}}==
<syntaxhighlight lang="xpl0">func ApproxEqual(A, B); \Return 'true' if approximately equal
real A, B;
real Epsilon;
[Epsilon:= abs(A) * 1E-15;
return abs(A-B) < Epsilon;
];
real Data;
int I;
[Format(0, 16);
Data:=[ [100000000000000.01, 100000000000000.011], \should return true
[100.01, 100.011], \should return false
[10000000000000.001 / 10000.0, 1000000000.0000001000],
[0.001, 0.0010000001],
[0.000000000000000000000101, 0.0], \is undefined
[sqrt(2.0) * sqrt(2.0), 2.0],
[-1.0 * sqrt(2.0) * sqrt(2.0), -2.0], \-sqrt doesn't compile!
[3.14159265358979323846, 3.14159265358979324] ];
for I:= 0 to 7 do
[IntOut(0, I+1); Text(0, ". ");
RlOut(0, Data(I,0)); ChOut(0, ^ ); RlOut(0, Data(I,1));
Text(0, if ApproxEqual(Data(I,0), Data(I,1)) then " true" else " false");
CrLf(0);
];
]</syntaxhighlight>
{{out}}
<pre>
1. 1.0000000000000000E+014 1.0000000000000000E+014 true
2. 1.0001000000000000E+002 1.0001100000000000E+002 false
3. 1.0000000000000000E+009 1.0000000000000000E+009 true
4. 1.0000000000000000E-003 1.0000001000000000E-003 false
5. 1.0100000000000000E-022 0.0000000000000000E+000 false
6. 2.0000000000000000E+000 2.0000000000000000E+000 true
7. -2.0000000000000000E+000 -2.0000000000000000E+000 true
8. 3.1415926535897900E+000 3.1415926535897900E+000 true
</pre>
=={{header|Yabasic}}==
<syntaxhighlight lang="yabasic">// Rosetta Code problem: http://rosettacode.org/wiki/Approximate_equality
// by Jjuanhdez, 09/2022
epsilon = 1.0
while (1 + epsilon <> 1)
epsilon = epsilon / 2
wend
print "epsilon = ", epsilon
print
eq_approx(100000000000000.01, 100000000000000.011)
eq_approx(100.01, 100.011)
eq_approx(10000000000000.001/10000.0, 1000000000.0000001000)
eq_approx(0.001, 0.0010000001)
eq_approx(0.000000000000000000000101, 0.0)
eq_approx(sqrt(2)*sqrt(2), 2.0)
eq_approx(-sqrt(2)*sqrt(2), -2.0)
eq_approx(3.14159265358979323846, 3.14159265358979324)
end
sub eq_approx(a, b)
tmp = abs(a - b) < epsilon
print tmp, " ", a, " ", b
end sub</syntaxhighlight>
=={{header|zkl}}==
Line 1,638 ⟶ 2,204:
and tolerance. If the tolerance is >=0, comparison is absolute.
If tolerance is <0 (and x!=0 and y!=0), the comparison is relative.
<
T(100000000000000.01,100000000000000.011),
T(100.01, 100.011),
Line 1,654 ⟶ 2,220:
maybeNot:=( if(x.closeTo(y,tolerance)) " \u2248" else "!\u2248" );
println("% 25.19g %s %- 25.19g %g".fmt(x,maybeNot,y, (x-y).abs()));
}</
{{out}}
|