I'm working on modernizing Rosetta Code's infrastructure. Starting with communications. Please accept this time-limited open invite to RC's Slack.. --Michael Mol (talk) 20:59, 30 May 2020 (UTC)

# Approximate equality

Approximate equality
You are encouraged to solve this task according to the task description, using any language you may know.

Sometimes, when testing whether the solution to a task (for example, here on Rosetta Code) is correct, the difference in floating point calculations between different language implementations becomes significant.

For example, a difference between 32 bit and 64 bit floating point calculations may appear by about the 8th significant digit in base 10 arithmetic.

Create a function which returns true if two floating point numbers are approximately equal.

The function should allow for differences in the magnitude of numbers, so that, for example,
100000000000000.01   may be approximately equal to   100000000000000.011,
even though   100.01   is not approximately equal to   100.011.

If the language has such a feature in its standard library, this may be used instead of a custom function.

Show the function results with comparisons on the following pairs of values:

1.     100000000000000.01,   100000000000000.011     (note: should return true)
2.     100.01,   100.011                                                     (note: should return false)
3.     10000000000000.001 / 10000.0,   1000000000.0000001000
4.     0.001,   0.0010000001
5.     0.000000000000000000000101,   0.0
6.      sqrt(2) * sqrt(2),    2.0
7.     -sqrt(2) * sqrt(2),   -2.0
8.     3.14159265358979323846,   3.14159265358979324

Answers should be true for the first example and false in the second, so that just rounding the numbers to a fixed number of decimals should not be enough. Otherwise answers may vary and still be correct. See the Python code for one type of solution.

` with Ada.Text_IO; use Ada.Text_IO;with Ada.Numerics.Generic_Elementary_Functions; procedure Main is   type Real is digits 18;   package Real_Funcs is new Ada.Numerics.Generic_Elementary_Functions(Real);   use Real_Funcs;   package Real_IO is new Ada.Text_IO.Float_IO(Real);   use Real_IO;    function Approx_Equal (Left : Real; Right : Real) return Boolean is       -- Calculate an epsilon value based upon the magnitude of the      -- maximum value of the two parameters      eps : Real := Real'Max(Left, Right) * 1.0e-9;   begin      if left > Right then         return Left - Right < eps;      else         return Right - Left < eps;      end if;   end Approx_Equal;    Type Index is (Left, Right);   type Pairs_List is array (Index) of Real;   type Pairs_Table is array(1..8) of Pairs_List;   Table : Pairs_Table; begin   Table := ((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));    for Pair of Table loop      Put(Item => Pair(Left), Exp => 0, Aft => 16, Fore => 6);      Put("  ");      Put(Item => Pair(Right), Exp => 0, Aft => 16, Fore => 6);      Put_Line("  " & Boolean'Image(Approx_Equal(Pair(Left), Pair(Right))));   end loop; end Main; `
Output:
```100000000000000.0100000000000000  100000000000000.0110000000000000  TRUE
100.0100000000000000     100.0110000000000000  FALSE
1000000000.0000001000000000  1000000000.0000001000000000  TRUE
0.0010000000000000       0.0010000001000000  FALSE
0.0000000000000000       0.0000000000000000  FALSE
2.0000000000000000       2.0000000000000000  TRUE
-2.0000000000000000      -2.0000000000000000  FALSE
3.1415926535897932       3.1415926535897932  TRUE
```

## ALGOL 68

Translation of: Kotlin
`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`
Output:
```+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
```

## AWK

` # syntax: GAWK -f APPROXIMATE_EQUALITY.AWK# converted from C#BEGIN {    epsilon = 1    while (1 + epsilon != 1) {      epsilon /= 2    }    printf("epsilon = %18.16g\n\n",epsilon)    main("100000000000000.01","100000000000000.011")    main("100.01","100.011")    main("10000000000000.001"/"10000.0","1000000000.0000001000")    main("0.001","0.0010000001")    main("0.000000000000000000000101","0.0")    main(sqrt(2.0)*sqrt(2.0),"2.0")    main(-sqrt(2.0)*sqrt(2.0),"-2.0")    main("3.14159265358979323846","3.14159265358979324")    exit(0)}function main(a,b,  tmp) {    tmp = abs(a - b) < epsilon    printf("%d %27s %s\n",tmp,a,b)}function abs(x) { if (x >= 0) { return x } else { return -x } } `
Output:
```epsilon = 1.110223024625157e-016

1          100000000000000.01 100000000000000.011
0                      100.01 100.011
0                      1e+009 1000000000.0000001000
0                       0.001 0.0010000001
1  0.000000000000000000000101 0.0
0                           2 2.0
0                          -2 -2.0
1      3.14159265358979323846 3.14159265358979324
```

## C

Translation of: Java
`#include <math.h>#include <stdbool.h>#include <stdio.h> bool approxEquals(double value, double other, double epsilon) {    return fabs(value - other) < epsilon;} void test(double a, double b) {    double epsilon = 1e-18;    printf("%f, %f => %d\n", a, b, approxEquals(a, b, epsilon));} int main() {    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);    return 0;}`
Output:
```100000000000000.015625, 100000000000000.015625 => 1
100.010000, 100.011000 => 0
1000000000.000000, 1000000000.000000 => 0
0.001000, 0.001000 => 0
0.000000, 0.000000 => 1
2.000000, 2.000000 => 0
-2.000000, -2.000000 => 0
3.141593, 3.141593 => 1```

## C#

`using System; public static class Program{    public static void Main() {        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(Math.Sqrt(2) * Math.Sqrt(2), 2.0);        Test(-Math.Sqrt(2) * Math.Sqrt(2), -2.0);        Test(3.14159265358979323846, 3.14159265358979324);         void Test(double a, double b) {            const double epsilon = 1e-18;            WriteLine(\$"{a}, {b} => {a.ApproxEquals(b, epsilon)}");        }    }     public static bool ApproxEquals(this double value, double other, double epsilon) => Math.Abs(value - other) < epsilon;}`
Output:
```100000000000000.02, 100000000000000.02 => True
100.01, 100.011 => False
1000000000.0000002, 1000000000.0000001 => False
0.001, 0.0010000001 => False
1.01E-22, 0 => True
2.0000000000000004, 2 => False
-2.0000000000000004, -2 => False
3.141592653589793, 3.141592653589793 => True```

## C++

Translation of: C
`#include <iomanip>#include <iostream>#include <cmath> bool approxEquals(double a, double b, double e) {    return fabs(a - b) < e;} void test(double a, double b) {    constexpr double epsilon = 1e-18;    std::cout << std::setprecision(21) << a;    std::cout << ", ";    std::cout << std::setprecision(21) << b;    std::cout << " => ";    std::cout << approxEquals(a, b, epsilon) << '\n';} int main() {    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);    return 0;}`
Output:
```100000000000000.015625, 100000000000000.015625 => 1
100.010000000000005116, 100.01099999999999568 => 0
1000000000.00000023842, 1000000000.00000011921 => 0
0.00100000000000000002082, 0.00100000010000000005492 => 0
1.0099999999999999762e-22, 0 => 1
2.00000000000000044409, 2 => 0
-2.00000000000000044409, -2 => 0
3.141592653589793116, 3.141592653589793116 => 1```

## 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.

` (defun approx-equal (float1 float2 &optional (threshold 0.000001))  "Determine whether float1 and float2 are equal; THRESHOLD is themaximum allowable difference between normalized significands of floatswith the same exponent. The significands are scaled appropriatelybefore 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))))) `

## D

Translation of: C#
`import std.math;import std.stdio; auto approxEquals = (double a, double b, double epsilon) => abs(a - b) < epsilon; void main() {    void test(double a, double b) {        double epsilon = 1e-18;        writefln("%.18f, %.18f => %s", a, b, a.approxEquals(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);}`
Output:
```100000000000000.015620000000000000, 100000000000000.015620000000000000 => true
100.010000000000005110, 100.010999999999995680 => false
1000000000.000000119100000000, 1000000000.000000119100000000 => true
0.001000000000000000, 0.001000000100000000 => false
0.000000000000000000, 0.000000000000000000 => true
2.000000000000000000, 2.000000000000000000 => true
-2.000000000000000000, -2.000000000000000000 => true
3.141592653589793116, 3.141592653589793116 => true```

## Delphi

Library: 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.

` program Approximate_Equality; {\$APPTYPE CONSOLE} uses  System.SysUtils,  System.Math; const  EPSILON: Double = 1E-18; procedure Test(a, b: Double; Expected: Boolean);var  result: Boolean;const  STATUS: array[Boolean] of string = ('FAIL', 'OK');begin  result := SameValue(a, b, EPSILON);  Write(a, ' ', b, ' => ', result, ' '^I);  writeln(Expected, ^I, STATUS[Expected = result]);end; begin  Test(100000000000000.01, 100000000000000.011, True);  Test(100.01, 100.011, False);  Test(double(10000000000000.001) / double(10000.0), double(1000000000.0000001000),    False);  Test(0.001, 0.0010000001, False);  Test(0.000000000000000000000101, 0.0, True);  Test(double(Sqrt(2)) * double(Sqrt(2)), 2.0, False);  Test(-double(Sqrt(2)) * double(Sqrt(2)), -2.0, false);  Test(3.14159265358979323846, 3.14159265358979324, True);  Readln;end.  `
Output:
``` 1.00000000000000E+0014  1.00000000000000E+0014 => TRUE         TRUE    OK
1.00010000000000E+0002  1.00011000000000E+0002 => FALSE        FALSE   OK
1.00000000000000E+0009  1.00000000000000E+0009 => FALSE        FALSE   OK
1.00000000000000E-0003  1.00000010000000E-0003 => FALSE        FALSE   OK
1.01000000000000E-0022  0.00000000000000E+0000 => TRUE         TRUE    OK
2.00000000000000E+0000  2.00000000000000E+0000 => FALSE        FALSE   OK
-2.00000000000000E+0000 -2.00000000000000E+0000 => FALSE        FALSE   OK
3.14159265358979E+0000  3.14159265358979E+0000 => TRUE         TRUE    OK
```

## Factor

The `~` 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 version 0.99 development version 2019-07-10
`USING: formatting generalizations kernel math math.functions ; 100000000000000.01             100000000000000.011100.01                         100.01110000000000000.001 10000.0 /f  1000000000.00000010000.001                          0.00100000010.000000000000000000000101     0.02 sqrt dup *                   2.02 sqrt dup neg *              -2.03.14159265358979323846         3.14159265358979324 [ 2dup -1e-15 ~ "%+47.30f %+47.30f -1e-15 ~ : %u\n" printf ]2 8 mnapply`
Output:
```+100000000000000.015625000000000000000000000000 +100000000000000.015625000000000000000000000000 -1e-15 ~ : t
+100.010000000000005115907697472721             +100.010999999999995679900166578591 -1e-15 ~ : f
+1000000000.000000238418579101562500000000      +1000000000.000000119209289550781250000000 -1e-15 ~ : t
+0.001000000000000000020816681712               +0.001000000100000000054917270731 -1e-15 ~ : f
+0.000000000000000000000101000000               +0.000000000000000000000000000000 -1e-15 ~ : f
+2.000000000000000444089209850063               +2.000000000000000000000000000000 -1e-15 ~ : t
-2.000000000000000444089209850063               -2.000000000000000000000000000000 -1e-15 ~ : t
+3.141592653589793115997963468544               +3.141592653589793115997963468544 -1e-15 ~ : t
```

## Forth

Works with: GForth version 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:

` : test-f~   ( f1 f2 -- )    1e-18                  \ epsilon  f~                     \ AproximateEqual  if ." True" else ." False" then   ;  `
Output:
```  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
```

## Fortran

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#

`program main  implicit none   integer                       :: i  double precision, allocatable :: vals(:)   vals = [ 100000000000000.01d0,          100000000000000.011d0,   &    &      100.01d0,                      100.011d0,               &    &      10000000000000.001d0/10000d0,  1000000000.0000001000d0, &    &      0.001d0,                       0.0010000001d0,          &    &      0.000000000000000000000101d0,  0d0,                     &    &      sqrt(2d0)*sqrt(2d0),           2d0,                     &    &     -sqrt(2d0)*sqrt(2d0),          -2d0,                     &    &      3.14159265358979323846d0,      3.14159265358979324d0    ]   do i = 1, size(vals)/2    print '(ES30.18, A, ES30.18, A, L)', vals(2*i-1), ' == ', vals(2*i), ' ? ', eq_approx(vals(2*i-1), vals(2*i))  end do contains   logical function eq_approx(a, b, reltol, abstol)    !! is a approximately equal b?     double precision, intent(in)           :: a, b      !! values to compare    double precision, intent(in), optional :: reltol, abstol      !! relative and absolute error thresholds.      !! defaults: epsilon, smallest non-denormal number     double precision :: rt, at     rt = epsilon(1d0)    at = tiny(1d0)    if (present(reltol)) rt = reltol    if (present(abstol)) at = abstol     eq_approx = abs(a - b) .le. max(rt * max(abs(a), abs(b)), at)    return  end function end program`
Output:
```      1.000000000000000156E+14 ==       1.000000000000000156E+14 ? T
1.000100000000000051E+02 ==       1.000109999999999957E+02 ? F
1.000000000000000238E+09 ==       1.000000000000000119E+09 ? T
1.000000000000000021E-03 ==       1.000000100000000055E-03 ? F
1.009999999999999976E-22 ==       0.000000000000000000E+00 ? F
2.000000000000000444E+00 ==       2.000000000000000000E+00 ? T
-2.000000000000000444E+00 ==      -2.000000000000000000E+00 ? T
3.141592653589793116E+00 ==       3.141592653589793116E+00 ? T```

## FreeBASIC

Translation of: AWK
`#include "string.bi" Dim Shared As Double epsilon = 1 Sub eq_approx(a As Double,b As Double)    Dim As Boolean tmp = Abs(a - b) < epsilon    Print Using "& & &";tmp;a;bEnd Sub While (1 + epsilon <> 1)    epsilon /= 2Wend Print "epsilon = "; Format(epsilon, "0.000000000000000e-00")Printeq_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(Sqr(2)*Sqr(2), 2.0)eq_approx(-Sqr(2)*Sqr(2), -2.0)eq_approx(3.14159265358979323846, 3.14159265358979324) Sleep`

## 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.

`package main import (    "fmt"    "log"    "math/big") func max(a, b *big.Float) *big.Float {    if a.Cmp(b) > 0 {        return a    }    return b} func isClose(a, b *big.Float) bool {    relTol := big.NewFloat(1e-9) // same as default for Python's math.isclose() function    t := new(big.Float)    t.Sub(a, b)    t.Abs(t)    u, v, w := new(big.Float), new(big.Float), new(big.Float)    u.Mul(relTol, max(v.Abs(a), w.Abs(b)))    return t.Cmp(u) <= 0} func nbf(s string) *big.Float {    n, ok := new(big.Float).SetString(s)    if !ok {        log.Fatal("invalid floating point number")    }    return n} func main() {    root2 := big.NewFloat(2.0)    root2.Sqrt(root2)    pairs := [][2]*big.Float{        {nbf("100000000000000.01"), nbf("100000000000000.011")},        {nbf("100.01"), nbf("100.011")},        {nbf("0").Quo(nbf("10000000000000.001"), nbf("10000.0")), nbf("1000000000.0000001000")},        {nbf("0.001"), nbf("0.0010000001")},        {nbf("0.000000000000000000000101"), nbf("0.0")},        {nbf("0").Mul(root2, root2), nbf("2.0")},        {nbf("0").Mul(nbf("0").Neg(root2), root2), nbf("-2.0")},        {nbf("100000000000000003.0"), nbf("100000000000000004.0")},        {nbf("3.14159265358979323846"), nbf("3.14159265358979324")},    }    for _, pair := range pairs {        s := "≉"        if isClose(pair[0], pair[1]) {            s = "≈"        }        fmt.Printf("% 21.19g %s %- 21.19g\n", pair[0], s, pair[1])    }}`
Output:
```   100000000000000.01 ≈  100000000000000.011
100.01 ≉  100.011
1000000000.0000001 ≈  1000000000.0000001
0.001 ≉  0.0010000001
1.01e-22 ≉  0
2.000000000000000273 ≈  2
-2.000000000000000273 ≈ -2
100000000000000003 ≈  100000000000000004
3.141592653589793239 ≈  3.14159265358979324
```

## Groovy

Translation of: Java
`class Approximate {    private static boolean approxEquals(double value, double other, double epsilon) {        return Math.abs(value - other) < epsilon    }     private static void test(double a, double b) {        double epsilon = 1e-18        System.out.printf("%f, %f => %s\n", a, b, approxEquals(a, b, epsilon))    }     static void main(String[] args) {        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(Math.sqrt(2.0) * Math.sqrt(2.0), 2.0)        test(-Math.sqrt(2.0) * Math.sqrt(2.0), -2.0)        test(3.14159265358979323846, 3.14159265358979324)    }}`
Output:
```100000000000000.020000, 100000000000000.020000 => true
100.010000, 100.011000 => false
1000000000.000000, 1000000000.000000 => true
0.001000, 0.001000 => false
0.000000, 0.000000 => true
2.000000, 2.000000 => false
-2.000000, -2.000000 => false
3.141593, 3.141593 => true```

`class (Num a, Ord a, Eq a) => AlmostEq a where  eps :: a infix 4 ~=(~=) :: AlmostEq a => a -> a -> Boola ~= b = or [ a == b            , abs (a - b) < eps * abs(a + b)            , abs (a - b) < eps ] instance AlmostEq Int where eps = 0instance AlmostEq Integer where eps = 0instance AlmostEq Double where eps = 1e-14instance AlmostEq Float where eps = 1e-5`

Examples

```λ> 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```

Assignment

`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.Printfmain = 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)`
```λ> 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```

## J

Attributed to Ken Iverson, inventor of APL and of course his final dialect, j, "In an early talk Ken was explaining the advantages of tolerant comparison. A member of the audience asked incredulously, “Surely you don’t mean that when A=B and B=C, A may not equal C?” Without skipping a beat, Ken replied, “Any carpenter knows that!” and went on to the next question."

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.

`    NB. default comparison tolerance matches the python result   ".;._2]0 :0      100000000000000.01 =   100000000000000.011      100.01 =   100.011                              (10000000000000.001 % 10000.0) =   1000000000.0000001000      0.001 =   0.0010000001      0.000000000000000000000101 =   0.0      (= ([: *~ %:)) 2                    NB. sqrt(2)*sqrt(2)      ((= -)~ ([: (* -) %:)) 2            NB. -sqrt(2) * sqrt(2),   -2.0      3.14159265358979323846 =   3.14159265358979324)1 0 1 0 0 1 1 1     NB. tolerance of 1e_12 matches the python result   ".;._2]0 :0[CT=:1e_12      100000000000000.01 =!.CT   100000000000000.011      100.01 =!.CT   100.011                              (10000000000000.001 % 10000.0) =!.CT   1000000000.0000001000      0.001 =!.CT   0.0010000001      0.000000000000000000000101 =!.CT   0.0      (=!.CT ([: *~ %:)) 2                    NB. sqrt(2)*sqrt(2)      ((=!.CT -)~ ([: (* -) %:)) 2            NB. -sqrt(2) * sqrt(2),   -2.0      3.14159265358979323846 =!.CT   3.14159265358979324)1 0 1 0 0 1 1 1     NB. tight tolerance   ".;._2]0 :0[CT=:1e_18      100000000000000.01 =!.CT   100000000000000.011      100.01 =!.CT   100.011                              (10000000000000.001 % 10000.0) =!.CT   1000000000.0000001000      0.001 =!.CT   0.0010000001      0.000000000000000000000101 =!.CT   0.0      (=!.CT ([: *~ %:)) 2                    NB. sqrt(2)*sqrt(2)      ((=!.CT -)~ ([: (* -) %:)) 2            NB. -sqrt(2) * sqrt(2),   -2.0      3.14159265358979323846 =!.CT   3.14159265358979324)1 0 0 0 0 0 0 1    2 (=!.1e_8) 9|domain error|   2(=    !.1e_8)9 `

## Java

Translation of: Kotlin
`public class Approximate {    private static boolean approxEquals(double value, double other, double epsilon) {        return Math.abs(value - other) < epsilon;    }     private static void test(double a, double b) {        double epsilon = 1e-18;        System.out.printf("%f, %f => %s\n", a, b, approxEquals(a, b, epsilon));    }     public static void main(String[] args) {        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(Math.sqrt(2.0) * Math.sqrt(2.0), 2.0);        test(-Math.sqrt(2.0) * Math.sqrt(2.0), -2.0);        test(3.14159265358979323846, 3.14159265358979324);    }}`
Output:
```100000000000000.020000, 100000000000000.020000 => true
100.010000, 100.011000 => false
1000000000.000000, 1000000000.000000 => false
0.001000, 0.001000 => false
0.000000, 0.000000 => true
2.000000, 2.000000 => false
-2.000000, -2.000000 => false
3.141593, 3.141593 => true```

## jq

Translation of: Lobster
`# 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 valuesdef 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)" `
Output:

Using jq 1.6:

`  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`

## Julia

Julia has an infix operator, ≈, which corresponds to Julia's buitin isapprox() function.

Translation of: Python
`testvalues = [[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.14159265358979323846,       3.14159265358979324]] for (x, y) in testvalues    println(rpad(x, 21), " ≈ ", lpad(y, 22), ": ", x ≈ y)end `
Output:
```1.0000000000000002e14 ≈  1.0000000000000002e14: true
100.01                ≈                100.011: false
1.0000000000000002e9  ≈   1.0000000000000001e9: true
0.001                 ≈           0.0010000001: false
1.01e-22              ≈                    0.0: false
2.0000000000000004    ≈                    2.0: true
-2.0000000000000004   ≈                   -2.0: true
3.141592653589793     ≈      3.141592653589793: true
```

## Kotlin

Translation of: C#
`import kotlin.math.absimport kotlin.math.sqrt fun approxEquals(value: Double, other: Double, epsilon: Double): Boolean {    return abs(value - other) < epsilon} fun test(a: Double, b: Double) {    val epsilon = 1e-18    println("\$a, \$b => \${approxEquals(a, b, epsilon)}")} fun main() {    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)}`
Output:
```1.0000000000000002E14, 1.0000000000000002E14 => true
100.01, 100.011 => false
1.0000000000000002E9, 1.0000000000000001E9 => false
0.001, 0.0010000001 => false
1.01E-22, 0.0 => true
2.0000000000000004, 2.0 => false
-2.0000000000000004, -2.0 => false
3.141592653589793, 3.141592653589793 => true```

## Lobster

Translation of: Rust
` // 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):    return abs(a - b) <= max(abs(a), abs(b)) * epsilon let tv = [    xy { 100000000000000.01, 100000000000000.011 },    xy { 100.01, 100.011 },    xy { 10000000000000.001 / 10000.0, 1000000000.0000001000 },    xy { 0.001, 0.0010000001 },    xy { 0.000000000000000000000101, 0.0 },    xy { sqrt(2.0) * sqrt(2.0), 2.0 },    xy { -sqrt(2.0) * sqrt(2.0), -2.0 },    xy { 3.14159265358979323846, 3.14159265358979324 }    ] for(tv) t:    print concat_string([string(t.x), if isclose(t.x, t.y, 1.0e-9): """ ≈ """ else: """ ≉ """, string(t.y)], "") `
Output:
```100000000000000.0 ≈ 100000000000000.0
100.01 ≉ 100.011
1000000000.0 ≈ 1000000000.0
0.001 ≉ 0.0010000001
0.0 ≉ 0.0
2.0 ≈ 2.0
-2.0 ≈ -2.0
3.14159265359 ≈ 3.14159265359
```

## Lua

Translation of: C
`function approxEquals(value, other, epsilon)    return math.abs(value - other) < epsilonend function test(a, b)    local epsilon = 1e-18    print(string.format("%f, %f => %s", a, b, tostring(approxEquals(a, b, epsilon))))end function main()    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(math.sqrt(2.0) * math.sqrt(2.0), 2.0)    test(-math.sqrt(2.0) * math.sqrt(2.0), -2.0)    test(3.14159265358979323846, 3.14159265358979324)end main()`
Output:
```100000000000000.020000, 100000000000000.020000 => true
100.010000, 100.011000 => false
1000000000.000000, 1000000000.000000 => false
0.001000, 0.001000 => false
0.000000, 0.000000 => true
2.000000, 2.000000 => false
-2.000000, -2.000000 => false
3.141593, 3.141593 => true```

## Mathematica/Wolfram Language

`ClearAll[CloseEnough]CloseEnough[a_, b_, tol_] := Chop[a - b, tol] == 0numbers = {   {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}   };(*[email protected]@Flatten[Map[MachineNumberQ,numbers,{2}]]*){#1, #2, CloseEnough[#1, #2, 10^-9]} & @@@ numbers // Grid`
Output:
```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```

## Nim

To compare the floating point values, we use a relative tolerance.

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.

`from math import sqrtimport strformatimport strutils const Tolerance = 1e-10 proc `~=`(a, b: float): bool =  ## Check if "a" and "b" are close.  ## We use a relative tolerance to compare the values.  result = abs(a - b) < max(abs(a), abs(b)) * Tolerance proc compare(a, b: string) =  ## Compare "a" and "b" transmitted as strings.  ## Values are computed using "parseFloat".  let r = a.parseFloat() ~= b.parseFloat()  echo fmt"{a} ~= {b} is {r}" proc compare(a: string; avalue: float; b: string) =  ## Compare "a" and "b" transmitted as strings.  ## The value of "a" is transmitted and not computed.  let r = avalue ~= b.parseFloat()  echo fmt"{a} ~= {b} is {r}"  compare("100000000000000.01", "100000000000000.011")compare("100.01", "100.011")compare("10000000000000.001 / 10000.0", 10000000000000.001 / 10000.0, "1000000000.0000001000")compare("0.001", "0.0010000001")compare("0.000000000000000000000101", "0.0")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")`
Output:
```100000000000000.01 ~= 100000000000000.011 is true
100.01 ~= 100.011 is false
10000000000000.001 / 10000.0 ~= 1000000000.0000001000 is true
0.001 ~= 0.0010000001 is false
0.000000000000000000000101 ~= 0.0 is false
sqrt(2) * sqrt(2) ~= 2.0 is true
-sqrt(2) * sqrt(2) ~= -2.0 is true
3.14159265358979323846 ~= 3.14159265358979324 is true```

## 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;;; `

## Perl

Passes task tests, but use the module `Test::Number::Delta` for anything of real importance.

`use strict;use warnings; sub is_close {    my(\$a,\$b,\$eps) = @_;    \$eps //= 15;    my \$epse = \$eps;    \$epse++ if sprintf("%.\${eps}f",\$a) =~ /\./;    \$epse++ if sprintf("%.\${eps}f",\$a) =~ /\-/;    my \$afmt = substr((sprintf "%.\${eps}f", \$a), 0, \$epse);    my \$bfmt = substr((sprintf "%.\${eps}f", \$b), 0, \$epse);    printf "%-5s %s ≅ %s\n", (\$afmt eq \$bfmt ? 'True' : 'False'), \$afmt, \$bfmt;} for (    [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],    [100000000000000003.0, 100000000000000004.0],    [3.14159265358979323846, 3.14159265358979324]    ) {        my(\$a,\$b) = @\$_;        is_close(\$a,\$b);} print "\nTolerance may be adjusted.\n";my \$real_pi  = 2 * atan2(1, 0);my \$roman_pi = 22/7;is_close(\$real_pi,\$roman_pi,\$_) for <10 3>;`
Output:
```True  100000000000000.0 ≅ 100000000000000.0
False 100.0100000000000 ≅ 100.0109999999999
True  1000000000.000000 ≅ 1000000000.000000
False 0.001000000000000 ≅ 0.001000000100000
True  0.000000000000000 ≅ 0.000000000000000
True  2.000000000000000 ≅ 2.000000000000000
True  -2.000000000000000 ≅ -2.000000000000000
True  10000000000000000 ≅ 10000000000000000
True  3.141592653589793 ≅ 3.141592653589793

Tolerance may be adjusted.
False 3.141592653 ≅ 3.142857142
True  3.14 ≅ 3.14```

## Phix

Traditionally I have always just used sprintf() to compare floating point atoms in phix.
This task (imo) is trying to make a general-purpose routine out of code which is best tailored for each and every specific task.
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.
I got a different result for test 4 to everyone else, but simply setting the cfmt to "%.10f" got it the NOT.
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.

```with javascript_semantics
procedure test(atom a,b, string dfmt="%g", cfmt="%g")
string ca = sprintf(cfmt,a),
cb = sprintf(cfmt,b),
eqs = iff(ca=cb?"":"NOT "),
da = sprintf(dfmt,a),
db = sprintf(dfmt,b)
printf(1,"%30s and\n%30s are %sapproximately equal\n",{da,db,eqs})
end procedure

test(100000000000000.01,100000000000000.011,"%.3f")
test(100.01,100.011,"%.3f")
test(10000000000000.001/10000.0,1000000000.0000001000,"%.10f")
test(0.001,0.0010000001,"%.10f")         -- both
test(0.001,0.0010000001,"%.10f","%.10f")  -- ways
test(0.000000000000000000000101,0.0,"%f")         -- both
test(0.000000000000000000000101,0.0,"%f","%6f")   -- ways
test(sqrt(2)*sqrt(2),2.0)
test(-sqrt(2)*sqrt(2),-2.0)
test(3.14159265358979323846,3.14159265358979324,"%.20f")
```
Output:

64 bit (implied by some of the accuracies specified for this task):

```           100000000000000.010 and
100000000000000.011 are approximately equal
100.010 and
100.011 are NOT approximately equal
1000000000.0000001001 and
1000000000.0000001000 are approximately equal
0.0010000000 and
0.0010000001 are approximately equal
0.0010000000 and
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
```

32 bit (in fact a couple of them, the first and last pairs, are actually genuinely identical):

```           100000000000000.016 and
100000000000000.016 are approximately equal
100.010 and
100.011 are NOT approximately equal
1000000000.0000002384 and
1000000000.0000001192 are approximately equal
0.0010000000 and
0.0010000001 are approximately equal
0.0010000000 and
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
```

## Python

The Python source documentation states:

```math.isclose -> bool
a: double
b: double
*
rel_tol: double = 1e-09
maximum difference for being considered "close", relative to the
magnitude of the input values
abs_tol: double = 0.0
maximum difference for being considered "close", regardless of the
magnitude of the input values
Determine whether two floating point numbers are close in value.
Return True if a is close in value to b, and False otherwise.
For the values to be considered close, the difference between them
must be smaller than at least one of the tolerances.
-inf, inf and NaN behave similarly to the IEEE 754 Standard.  That
is, NaN is not close to anything, even itself.  inf and -inf are
only close to themselves.
```
`from numpy import sqrtfrom math import isclose testvalues = [[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.14159265358979323846,       3.14159265358979324]] for (x, y) in testvalues:    maybenot = "is" if isclose(x, y) else "is NOT"    print(x, maybenot, "approximately equal to ", y)  `
Output:
```100000000000000.02 is approximately equal to  100000000000000.02
100.01 is NOT approximately equal to  100.011
1000000000.0000002 is approximately equal to  1000000000.0000001
0.001 is NOT approximately equal to  0.0010000001
1.01e-22 is NOT approximately equal to  0.0
2.0 is approximately equal to  2.0
-2.0 is approximately equal to  -2.0
3.141592653589793 is approximately equal to  3.141592653589793
```

## 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.

`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, ": ")))`
Output:
```                                                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```

## Racket

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 `#e`, it is now considered an exact, rational number. In this task, we test the approximate equality on both variants:

`#lang racket (define (≈ a b [tolerance 1e-9])  (<= (abs (/ (- a b) (max a b))) tolerance)) (define all-tests  `(([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]     [100000000000000003.0 100000000000000004.0]     [3.14159265358979323846 3.14159265358979324])    ([#e100000000000000.01 #e100000000000000.011]     [#e100.01 #e100.011]     [,(/ #e10000000000000.001 #e10000.0) #e1000000000.0000001000]     [#e0.001 #e0.0010000001]     [#e0.000000000000000000000101 #e0.0]     [,(* (sqrt 2) (sqrt 2)) #e2.0]     [,(* (- (sqrt 2)) (sqrt 2)) #e-2.0]     [100000000000000003 100000000000000004]     [#e3.14159265358979323846 #e3.14159265358979324]))) (define (format-num x)  (~a (~r x #:precision 30) #:min-width 50 #:align 'right)) (for ([tests (in-list all-tests)] [name '("inexact" "exact")])  (printf "~a:\n" name)  (for ([test (in-list tests)])    (match-define (list a b) test)    (printf "~a ~a: ~a\n" (format-num a) (format-num b) (≈ a b)))  (newline))`
Output:
```inexact:
100000000000000.015625000000000000310697263104     100000000000000.015625000000000000310697263104: #t
100.010000000000005116710235406336                 100.010999999999995680439855480832: #f
1000000000.000000238418579101562504740864          1000000000.000000119209289550781252370432: #t
0.001000000000000000013287555072                   0.001000000100000000093229940736: #f
0.000000000000000000000101                                                  0: #f
2.000000000000000444089209850063                                                  2: #t
-2.000000000000000444089209850063                                                 -2: #t
100000000000000000                                 100000000000000000: #t
3.141592653589793121575456735232                   3.141592653589793121575456735232: #t

exact:
100000000000000.01                                100000000000000.011: #t
100.01                                            100.011: #f
1000000000.0000001                                 1000000000.0000001: #t
0.001                                       0.0010000001: #f
0.000000000000000000000101                                                  0: #f
2.000000000000000444089209850063                                                  2: #t
-2.000000000000000444089209850063                                                 -2: #t
100000000000000003                                 100000000000000004: #t
3.14159265358979323846                                3.14159265358979324: #t
```

## Raku

(formerly Perl 6)

Works with: Rakudo version 2019.07.1

Is approximately equal to is a built-in operator in Raku. Unicode ≅, or the ASCII equivalent: =~=. By default it uses a tolerance of 1e-15 times the order of magnitude of the larger comparand, though that is adjustable by setting the dynamic variable \$*TOLERANCE to the desired value. Probably a good idea to localize the changed \$*TOLERANCE as it will affect all comparisons within its scope.

Most of the following tests are somewhat pointless in Raku. To a large extent, when dealing with Rational values, you don't really need to worry about "approximately equal to", and all of the test values below, with the exception of `sqrt(2)`, are Rats by default, and exact. You would have to specifically coerce them to Nums (floating point) to lose the precision.

For example, in Raku, the sum of .1, .2, .3, & .4 is identically equal to 1.

`say 0.1 + 0.2 + 0.3 + 0.4 === 1.0000000000000000000000000000000000000000000000000000000000000000000000000; # True`

It's also approximately equal to 1 but... ¯\_(ツ)_/¯

`for    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,    100000000000000003.0, 100000000000000004.0,    3.14159265358979323846, 3.14159265358979324   -> \$a, \$b {    say "\$a ≅ \$b: ", \$a ≅ \$b;} say "\nTolerance may be adjusted."; say 22/7, " ≅ ", π, ": ", 22/7 ≅ π;{ # Localize the tolerance to only this block  my \$*TOLERANCE = .001;  say 22/7, " ≅ ", π, ": ", 22/7 ≅ π;}`
Output:
```100000000000000.01 ≅ 100000000000000.011: True
100.01 ≅ 100.011: False
1000000000.0000001 ≅ 1000000000.0000001: True
0.001 ≅ 0.0010000001: False
0.000000000000000000000101 ≅ 0: True
2.0000000000000004 ≅ 2: True
-2.0000000000000004 ≅ -2: True
100000000000000003 ≅ 100000000000000004: True
3.141592653589793226752 ≅ 3.14159265358979324: True

Tolerance may be adjusted.
3.142857 ≅ 3.141592653589793: False
3.142857 ≅ 3.141592653589793: True```

## 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)} `

## REXX

Since the REXX language uses decimal digits (characters) for floating point numbers (and integers),   it's just a matter of
choosing the   number   of decimal digits for the precision to be used for arithmetic   (in this case, fifteen decimal digits).

The choosing of the number of decimal digits is performed via the REXX statement:   numeric digits   nnn

`/*REXX program mimics an  "approximately equal to"  for comparing floating point numbers*/numeric digits 15                                /*what other FP hardware normally uses.*/@.=                                              /*assign default for the   @   array.  */parse arg @.1                                    /*obtain optional argument from the CL.*/if @.1=''  |  @.1==","  then do;   @.1= 100000000000000.01           100000000000000.011                                   @.2= 100.01                       100.011                                   @.3= 10000000000000.001 / 10000   1000000000.0000001000                                   @.4= 0.001                        0.0010000001                                   @.5= 0.00000000000000000000101    0.0                                   @.6=  sqrt(2) * sqrt(2)           2.0                                   @.7= -sqrt(2) * sqrt(2)           '-2.0'                                   @.8= 3.14159265358979323846       3.14159265358979324          /* added ───► */         @.9= 100000000000000003.0         100000000000000004.0                             end     do j=1  while @.j\==''                      /*process CL argument or the array #s. */     say     say center(' processing pair ' j" ",71,'═') /*display a title for the pair of #s.  */     parse value  @.j  with  a  b                /*extract two values from a pair of #s.*/     say 'A='   a                                /*display the value of  A  to the term.*/     say 'B='   b                                /*   "     "    "    "  B   "  "    "  */     say right('A approximately equal to B?', 65)   word("false true", 1 + approxEQ(a,b) )     end   /*j*/                                 /* [↑]  right─justify text & true/false*/exit                                             /*stick a fork in it,  we're all done. *//*──────────────────────────────────────────────────────────────────────────────────────*/approxEQ: procedure; parse arg x,y;   return x=y /*floating point compare with 15 digits*//*──────────────────────────────────────────────────────────────────────────────────────*/sqrt: procedure; parse arg x;  if x=0  then return 0;  d=digits();  numeric digits;  h=d+6      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`
output   when using the internal default inputs:
```═════════════════════════ processing pair  1 ══════════════════════════
A= 100000000000000.01
B= 100000000000000.011
A approximately equal to B? true

═════════════════════════ processing pair  2 ══════════════════════════
A= 100.01
B= 100.011
A approximately equal to B? false

═════════════════════════ processing pair  3 ══════════════════════════
A= 1000000000
B= 1000000000.0000001000
A approximately equal to B? true

═════════════════════════ processing pair  4 ══════════════════════════
A= 0.001
B= 0.0010000001
A approximately equal to B? false

═════════════════════════ processing pair  5 ══════════════════════════
A= 0.00000000000000000000101
B= 0.0
A approximately equal to B? false

═════════════════════════ processing pair  6 ══════════════════════════
A= 2.00000000000000
B= 2.0
A approximately equal to B? true

═════════════════════════ processing pair  7 ══════════════════════════
A= -2.00000000000000
B= -2.0
A approximately equal to B? true

═════════════════════════ processing pair  8 ══════════════════════════
A= 3.14159265358979323846
B= 3.14159265358979324
A approximately equal to B? true

═════════════════════════ processing pair  9 ══════════════════════════
A= 100000000000000003.0
B= 100000000000000004.0
A approximately equal to B? true
```

## Ruby

Most work went into handling weird Float values like NaN and Infinity.

`require "bigdecimal" testvalues = [[100000000000000.01,           100000000000000.011],              [100.01,                       100.011],              [10000000000000.001 / 10000.0, 1000000000.0000001000],              [0.001,                        0.0010000001],              [0.000000000000000000000101,   0.0],              [(2**0.5) * (2**0.5),            2.0],              [-(2**0.5) * (2**0.5),          -2.0],              [BigDecimal("3.14159265358979323846"),       3.14159265358979324],              [Float::NAN, Float::NAN,],              [Float::INFINITY, Float::INFINITY],               ] class  Numeric  def close_to?(num, tol = Float::EPSILON)    return true  if self == num    return false if (self.to_f.nan? or num.to_f.nan?)        # NaN is not even close to itself    return false if [self, num].count( Float::INFINITY) == 1 # Infinity is only close to itself    return false if [self, num].count(-Float::INFINITY) == 1    (self-num).abs <= tol * ([self.abs, num.abs].max)  endend testvalues.each do |a,b|  puts "#{a} #{a.close_to?(b) ? '≈' : '≉'} #{b}"end `
Output:
```100000000000000.02 ≈ 100000000000000.02
100.01 ≉ 100.011
1000000000.0000002 ≈ 1000000000.0000001
0.001 ≉ 0.0010000001
0.101e-21 ≉ 0.0
2.0000000000000004 ≈ 2.0
-2.0000000000000004 ≈ -2.0
0.314159265358979323846e1 ≈ 3.141592653589793
NaN ≉ NaN
Infinity ≈ Infinity
```

## Rust

`/// 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)).fn isclose(a: f64, b: f64, epsilon: f64) -> bool {    (a - b).abs() <= a.abs().max(b.abs()) * epsilon} fn main() {    fn sqrt(x: f64) -> f64 { x.sqrt() }    macro_rules! test {        (\$a: expr, \$b: expr) => {            let operator = if isclose(\$a, \$b, 1.0e-9) { '≈' } else { '≉' };            println!("{:>28} {} {}", stringify!(\$a), operator, stringify!(\$b))        }    }     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);}`
Output:
```          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```

## Scala

Output:
Best seen running in your browser by Scastie (remote JVM).
`object Approximate extends App {  val (ok, notOk, ε) = ("👌", "❌", 1e-18d)   private def approxEquals(value: Double, other: Double, epsilon: Double) =    scala.math.abs(value - other) < epsilon   private def test(a: BigDecimal, b: BigDecimal, expected: Boolean): Unit = {    val result = approxEquals(a.toDouble, b.toDouble, ε)    println(f"\$a%40.24f ≅ \$b%40.24f => \$result%5s \${if (expected == result) ok else notOk}")  }   test(BigDecimal("100000000000000.010"), BigDecimal("100000000000000.011"), true)  test(BigDecimal("100.01"), BigDecimal("100.011"), false)  test(BigDecimal(10000000000000.001 / 10000.0), BigDecimal("1000000000.0000001000"), false)  test(BigDecimal("0.001"), BigDecimal("0.0010000001"), false)  test(BigDecimal("0.000000000000000000000101"), BigDecimal(0), true)  test(BigDecimal(math.sqrt(2) * math.sqrt(2d)), BigDecimal(2.0), false)  test(BigDecimal(-Math.sqrt(2) * Math.sqrt(2)), BigDecimal(-2.0), false)  test(BigDecimal("3.14159265358979323846"), BigDecimal("3.14159265358979324"), true)}`

## 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,    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,    sqrt(-2) * sqrt(-2), -2.0,    cbrt(3)**3, 3,    cbrt(-3)**3, -3,    100000000000000003.0, 100000000000000004.0,    3.14159265358979323846, 3.14159265358979324].each_slice(2, {|a,b|    say ("#{a} ≅ #{b}: ", a ≅ b)})`
Output:
```100000000000000.01 ≅ 100000000000000.011: false
100.01 ≅ 100.011: false
1000000000.0000001 ≅ 1000000000.0000001: true
0.001 ≅ 0.0010000001: false
0.000000000000000000000101 ≅ 0: false
2 ≅ 2: true
-2 ≅ -2: true
-2 ≅ -2: true
3 ≅ 3: true
-3-7.82914889268316957969274243345625157631318402415e-58i ≅ -3: true
100000000000000003 ≅ 100000000000000004: false
3.14159265358979323846 ≅ 3.14159265358979324: false
```

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 a = 100000000000000.01var b = 100000000000000.011 # Rounding at 2 and 3 decimal places, respectivelysay (round(a, -2) == round(b, -2))      # truesay (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 a = 22/7var 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)`
Output:
```22/7 ≅ π at 2 decimals: true
22/7 ≅ π at 3 decimals: false
```

Additionally, the rat_approx method can be used for computing a very good rational approximation to a given real value:

`say (1.33333333.rat_approx == 4/3)   # truesay (zeta(-5).rat_approx == -1/252)  # true`

Rational approximations illustrated for substrings of PI:

`for k in (3..19) {    var r = Str(Num.pi).first(k)    say ("rat_approx(#{r}) = ", Num(r).rat_approx.as_frac)}`
Output:
```rat_approx(3.1) = 31/10
rat_approx(3.14) = 22/7
rat_approx(3.141) = 245/78
rat_approx(3.1415) = 333/106
rat_approx(3.14159) = 355/113
rat_approx(3.141592) = 355/113
rat_approx(3.1415926) = 86953/27678
rat_approx(3.14159265) = 102928/32763
rat_approx(3.141592653) = 103993/33102
rat_approx(3.1415926535) = 1354394/431117
rat_approx(3.14159265358) = 833719/265381
rat_approx(3.141592653589) = 17925491/5705861
rat_approx(3.1415926535897) = 126312511/40206521
rat_approx(3.14159265358979) = 144029661/45846065
rat_approx(3.141592653589793) = 325994779/103767361
rat_approx(3.1415926535897932) = 903259831/287516534
rat_approx(3.14159265358979323) = 1726375805/549522486
```

## Smalltalk

This compares numbers given the number of ULPs by which they may differ (see wikipedia). 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
`{ #(100000000000000.01 100000000000000.011) .  #(100.01 100.011) .  {10000000000000.001 / 10000.0 . 1000000000.0000001000} .  #(0.001 0.0010000001) .  #(0.000000000000000000000101 0.0) .  { 2 sqrt * 2 sqrt . 2.0} .  { 2 sqrt negated * 2 sqrt . -2.0} .  #(3.14159265358979323846  3.14159265358979324)} pairsDo:[:val1 :val2 |   Stdout printCR: e'{val1} =~= {val2} -> {val1 isAlmostEqualTo:val2 nEpsilon:2}']`

In CUIS, this method is called isWithin:floatsFrom:.

Output:
```100.01 =~= 100.011 -> false
1000000000.0 =~= 1000000000.0 -> true
0.001 =~= 0.0010000001 -> false
1.01e-22 =~= 0.0 -> true
2.0 =~= 2.0 -> true
-2.0 =~= -2.0 -> true
3.14159265358979 =~= 3.14159265358979 -> true```

By default, double precision IEEE floats are used.

## Swift

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.

`import Foundation extension FloatingPoint {  @inlinable  public func isAlmostEqual(    to other: Self,    tolerance: Self = Self.ulpOfOne.squareRoot()  ) -> Bool {    // tolerances outside of [.ulpOfOne,1) yield well-defined but useless results,    // so this is enforced by an assert rathern than a precondition.    assert(tolerance >= .ulpOfOne && tolerance < 1, "tolerance should be in [.ulpOfOne, 1).")     // The simple computation below does not necessarily give sensible    // results if one of self or other is infinite; we need to rescale    // the computation in that case.    guard self.isFinite && other.isFinite else {      return rescaledAlmostEqual(to: other, tolerance: tolerance)    }     // This should eventually be rewritten to use a scaling facility to be    // defined on FloatingPoint suitable for hypot and scaled sums, but the    // following is good enough to be useful for now.    let scale = max(abs(self), abs(other), .leastNormalMagnitude)    return abs(self - other) < scale*tolerance  }   @usableFromInline  internal func rescaledAlmostEqual(to other: Self, tolerance: Self) -> Bool {    // NaN is considered to be not approximately equal to anything, not even    // itself.    if self.isNaN || other.isNaN { return false }    if self.isInfinite {      if other.isInfinite { return self == other }       // Self is infinite and other is finite. Replace self with the binade      // of the greatestFiniteMagnitude, and reduce the exponent of other by      // one to compensate.      let scaledSelf = Self(sign: self.sign,        exponent: Self.greatestFiniteMagnitude.exponent,        significand: 1)      let scaledOther = Self(sign: .plus,        exponent: -1,        significand: other)       // Now both values are finite, so re-run the naive comparison.      return scaledSelf.isAlmostEqual(to: scaledOther, tolerance: tolerance)    }     // If self is finite and other is infinite, flip order and use scaling    // defined above, since this relation is symmetric.    return other.rescaledAlmostEqual(to: self, tolerance: tolerance)  }} let testCases = [  (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.14159265358979323846, 3.14159265358979324)] for testCase in testCases {  print("\(testCase.0), \(testCase.1) => \(testCase.0.isAlmostEqual(to: testCase.1))")}`
Output:
```100000000000000.02, 100000000000000.02 => true
100.01, 100.011 => false
1000000000.0000002, 1000000000.0000001 => true
0.001, 0.0010000001 => false
1.01e-22, 0.0 => false
2.0000000000000004, 2.0 => true
-2.0000000000000004, -2.0 => true
3.141592653589793, 3.141592653589793 => true```

## Tcl

### Using decimal library

Uses tcllib's decimal library. Using a tolerance of 9 significant digits.

`catch {namespace delete test_almost_equal_decimal} ;# Start with a clean namespace namespace eval test_almost_equal_decimal {    package require Tcl 8.5 ;# required by tcllib    package require math::decimal ;# from tcllib    namespace import ::math::decimal::* ;# for: setVariable, fromstr, and compare     array set yesno {0 Yes -1 No 1 No} ;# For nice output     # More info here: http://speleotrove.com/decimal/dax3274.html    # This puts the library into "simplified" mode. Which    # rounds the "decimal digits" in the coefficient to the    # number of digits that "precision" is set to.    setVariable extended 0    setVariable precision 9     set data {        {100000000000000.01 100000000000000.011}        {100.01 100.011}        {[expr {10000000000000.001 / 10000.0}] 1000000000.0000001000}        {0.001 0.0010000001}        {0.000000000000000000000101 0.0}        {[expr { sqrt(2) * sqrt(2)}] 2.0}        {[expr {-sqrt(2) * sqrt(2)}] -2.0}        {3.14159265358979323846 3.14159265358979324}    }    set data [subst \$data] ;# resolves expressions in the list     foreach {a b} [join \$data] {        set a_d [fromstr \$a]        set b_d [fromstr \$b]         puts [format "Is %26s ≈ %21s ? %4s." \$a \$b \$yesno([compare \$a_d \$b_d])]    }} `
Output:
```Is         100000000000000.01 ≈   100000000000000.011 ?  Yes.
Is                     100.01 ≈               100.011 ?   No.
Is         1000000000.0000002 ≈ 1000000000.0000001000 ?  Yes.
Is                      0.001 ≈          0.0010000001 ?   No.
Is 0.000000000000000000000101 ≈                   0.0 ?   No.
Is         2.0000000000000004 ≈                   2.0 ?  Yes.
Is        -2.0000000000000004 ≈                  -2.0 ?  Yes.
Is     3.14159265358979323846 ≈   3.14159265358979324 ?  Yes.
```

### Using string manipulation

`catch {namespace delete test_almost_equal_string} ;# Start with a clean namespace namespace eval test_almost_equal_string {    package require Tcl 8.4 ;# ?Maybe earlier?    array set yesno {1 Yes 0 No} ;# For nice output     proc isClose {a b {prec 9}} {        proc toCoeff {n prec} {            set repr 40 ;# Chosen to be arbitrarily large to handle most cases            set long [format %0.\${repr}f \$n] ;# Take out of scientific notation            set map [string map {. {}} \$long] ;# Remove decimal point            set trim [string trimleft \$map 0] ;# Remove leading zeros            # restore string for comparison            set len [string length \$trim]            if {\$len < \$prec} {                set trim "\${trim}[string repeat 0 [expr (\$prec+1)-\$len]]"            }            # Round last decimal place            set rounded [format %0.f "[string range \$trim 0 [expr {\$prec-1}]].[string index \$trim \$prec]"]            return \$rounded        }        set a_coeff [toCoeff \$a \$prec]        set b_coeff [toCoeff \$b \$prec]         return [expr {\$a_coeff == \$b_coeff}]    }     set data {        {100000000000000.01 100000000000000.011}        {100.01 100.011}        {[expr {10000000000000.001 / 10000.0}] 1000000000.0000001000}        {0.001 0.0010000001}        {0.000000000000000000000101 0.0}        {[expr { sqrt(2) * sqrt(2)}] 2.0}        {[expr {-sqrt(2) * sqrt(2)}] -2.0}        {3.14159265358979323846 3.14159265358979324}    }    set data [subst \$data] ;# resolves expressions in the list     foreach {a b} [join \$data] {        puts [format "Is %26s ≈ %21s ? %4s." \$a \$b \$yesno([isClose \$a \$b])]    }} `
Output:
```Is         100000000000000.01 ≈   100000000000000.011 ?  Yes.
Is                     100.01 ≈               100.011 ?   No.
Is         1000000000.0000002 ≈ 1000000000.0000001000 ?  Yes.
Is                      0.001 ≈          0.0010000001 ?   No.
Is 0.000000000000000000000101 ≈                   0.0 ?   No.
Is         2.0000000000000004 ≈                   2.0 ?  Yes.
Is        -2.0000000000000004 ≈                  -2.0 ?  Yes.
Is     3.14159265358979323846 ≈   3.14159265358979324 ?  Yes.
```

## Visual Basic .NET

Translation of: C#
`Imports System.Runtime.CompilerServices Module Module1     <Extension()>    Function ApproxEquals(ByVal value As Double, other As Double, epsilon As Double)        Return Math.Abs(value - other) < epsilon    End Function     Sub Test(a As Double, b As Double)        Dim epsilon = 1.0E-18        Console.WriteLine(\$"{a}, {b} => {a.ApproxEquals(b, epsilon)}")    End Sub     Sub Main()        Test(100000000000000.02, 100000000000000.02)        Test(100.01, 100.011)        Test(10000000000000.002 / 10000.0, 1000000000.0000001)        Test(0.001, 0.0010000001)        Test(1.01E-22, 0.0)        Test(Math.Sqrt(2) * Math.Sqrt(2), 2.0)        Test(-Math.Sqrt(2) * Math.Sqrt(2), -2.0)        Test(3.1415926535897931, 3.1415926535897931)    End Sub End Module`
Output:
```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.14159265358979, 3.14159265358979 => True```

## Wren

`var tol = 1e-16var pairs = [    [100000000000000.01, 100000000000000.011],    [100.01, 100.011],    [10000000000000.001 / 10000.0, 1000000000.0000001000],    [0.001, 0.0010000001],    [0.000000000000000000000101, 0.0],    [2.sqrt * 2.sqrt, 2.0],    [-2.sqrt * 2.sqrt, -2.0],    [3.14159265358979323846, 3.14159265358979324]]System.print("Approximate equality of test cases for a tolerance of %(tol):")var i = 0for (pair in pairs) {    i = i + 1    System.print("  %(i) -> %((pair[0] - pair[1]).abs < tol)")}`
Output:
```Approximate equality of test cases for a tolerance of 1e-16:
1 -> true
2 -> false
3 -> false
4 -> false
5 -> true
6 -> false
7 -> false
8 -> true
```

## XPL0

`func ApproxEqual(A, B);         \Return 'true' if approximately equalreal 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);        ];]`
Output:
```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
```

## zkl

Floats are 64 bit and have the closeTo method, which takes a comparison value and tolerance. If the tolerance is >=0, comparison is absolute. If tolerance is <0 (and x!=0 and y!=0), the comparison is relative.

`testValues:=T(    T(100000000000000.01,100000000000000.011),   T(100.01, 100.011),   T(10000000000000.001 / 10000.0, 1000000000.0000001),   T(0.001, 0.0010000001),   T(0.00000000000000000101, 0.0),   T(  (2.0).sqrt()*(2.0).sqrt(),  2.0),   T( -(2.0).sqrt()*(2.0).sqrt(), -2.0),   T(100000000000000003.0, 100000000000000004.0),   T(3.14159265358979323846, 3.14159265358979324) ); tolerance:=-1e-9;	// <0 for relative comparisonforeach x,y in (testValues){   maybeNot:=( if(x.closeTo(y,tolerance)) " \u2248" else "!\u2248" );   println("% 25.19g %s %- 25.19g  %g".fmt(x,maybeNot,y, (x-y).abs()));}`
Output:
```     100000000000000.0156  ≈  100000000000000.0156      0
100.0100000000000051 !≈  100.0109999999999957      0.001
1000000000.000000238  ≈  1000000000.000000119      1.19209e-07
0.001000000000000000021 !≈  0.001000000100000000055   1e-10
1.010000000000000018e-18 !≈  0                         1.01e-18
2.000000000000000444  ≈  2                         4.44089e-16
-2.000000000000000444  ≈ -2                         4.44089e-16
100000000000000000  ≈  100000000000000000        0
3.141592653589793116  ≈  3.141592653589793116      0
```