Approximate equality: Difference between revisions

m
→‎{{header|Wren}}: Changed to Wren S/H
m (s)
m (→‎{{header|Wren}}: Changed to Wren S/H)
 
(15 intermediate revisions by 5 users not shown)
Line 34:
 
=={{header|Ada}}==
<syntaxhighlight lang=Ada"ada">
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Numerics.Generic_Elementary_Functions;
Line 96:
=={{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;
Line 128:
 
=={{header|AWK}}==
<syntaxhighlight lang=AWK"awk">
# syntax: GAWK -f APPROXIMATE_EQUALITY.AWK
# converted from C#
Line 169:
=={{header|C}}==
{{trans|Java}}
<syntaxhighlight lang="c">#include <math.h>
#include <stdbool.h>
#include <stdio.h>
Line 204:
 
=={{header|C sharp|C#}}==
<syntaxhighlight lang="csharp">using System;
 
public static class Program
Line 239:
=={{header|C++}}==
{{trans|C}}
<syntaxhighlight lang="cpp">#include <iomanip>
#include <iostream>
#include <cmath>
Line 280:
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
Line 295:
=={{header|D}}==
{{trans|C#}}
<syntaxhighlight lang="d">import std.math;
import std.stdio;
 
Line 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"delphi">
program Approximate_Equality;
 
Line 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}}
<syntaxhighlight lang="factor">USING: formatting generalizations kernel math math.functions ;
 
100000000000000.01 100000000000000.011
Line 411:
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
Line 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#
<syntaxhighlight lang="fortran">program main
implicit none
 
Line 488:
=={{header|FreeBASIC}}==
{{trans|AWK}}
<syntaxhighlight lang="freebasic">#include "string.bi"
 
Dim Shared As Double epsilon = 1
Line 514:
Sleep</syntaxhighlight>
 
=={{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.
<syntaxhighlight lang="go">package main
 
import (
Line 588 ⟶ 629:
=={{header|Groovy}}==
{{trans|Java}}
<syntaxhighlight lang="groovy">class Approximate {
private static boolean approxEquals(double value, double other, double epsilon) {
return Math.abs(value - other) < epsilon
Line 620 ⟶ 661:
 
=={{header|Haskell}}==
<syntaxhighlight lang="haskell">class (Num a, Ord a, Eq a) => AlmostEq a where
eps :: a
 
Line 653 ⟶ 694:
Assignment
 
<syntaxhighlight lang="haskell">test :: [(Double, Double)]
test = [(100000000000000.01, 100000000000000.011)
,(100.01, 100.011)
Line 705 ⟶ 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 754 ⟶ 795:
=={{header|Java}}==
{{trans|Kotlin}}
<syntaxhighlight lang="java">public class Approximate {
private static boolean approxEquals(double value, double other, double epsilon) {
return Math.abs(value - other) < epsilon;
Line 787 ⟶ 828:
=={{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
Line 815 ⟶ 856:
{{out}}
Using jq 1.6:
<syntaxhighlight lang="sh"> 100000000000000.02 ≈ 100000000000000.02
100.01 ≉ 100.011
1000000000.0000002 ≈ 1000000000.0000001
Line 827 ⟶ 868:
Julia has an infix operator, ≈, which corresponds to Julia's buitin isapprox() function.
{{trans|Python}}
<syntaxhighlight lang="julia">testvalues = [[100000000000000.01, 100000000000000.011],
[100.01, 100.011],
[10000000000000.001 / 10000.0, 1000000000.0000001000],
Line 853 ⟶ 894:
=={{header|Kotlin}}==
{{trans|C#}}
<syntaxhighlight lang="scala">import kotlin.math.abs
import kotlin.math.sqrt
 
Line 887 ⟶ 928:
=={{header|Lobster}}==
{{trans|Rust}}
<syntaxhighlight lang=Lobster"lobster">
// Return whether the two numbers `a` and `b` are close.
// Closeness is determined by the `epsilon` parameter -
Line 924 ⟶ 965:
=={{header|Lua}}==
{{trans|C}}
<syntaxhighlight lang="lua">function approxEquals(value, other, epsilon)
return math.abs(value - other) < epsilon
end
Line 956 ⟶ 997:
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<syntaxhighlight lang=Mathematica"mathematica">ClearAll[CloseEnough]
CloseEnough[a_, b_, tol_] := Chop[a - b, tol] == 0
numbers = {
Line 984 ⟶ 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.
 
<syntaxhighlight lang=Nim"nim">from math import sqrt
import strformat
import strutils
Line 1,028 ⟶ 1,069:
 
=={{header|OCaml}}==
<syntaxhighlight lang="ocaml">let approx_eq v1 v2 epsilon =
Float.abs (v1 -. v2) < epsilon
 
Line 1,051 ⟶ 1,092:
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.&nbsp;e. it is up to the compiler vendors to assign concrete values to them.
<syntaxhighlight lang="pascal">program approximateEqual(output);
 
{
Line 1,137 ⟶ 1,178:
=={{header|Perl}}==
Passes task tests, but use the module <code>Test::Number::Delta</code> for anything of real importance.
<syntaxhighlight lang="perl">use strict;
use warnings;
 
Line 1,191 ⟶ 1,232:
I got a different result for test 4 to everyone else, but simply setting the cfmt to "%.10f" got it the NOT.<br>
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"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>
Line 1,259 ⟶ 1,300:
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 1,282 ⟶ 1,365:
only close to themselves.
</pre>
<syntaxhighlight lang="python">from numpy import sqrt
from math import isclose
 
Line 1,311 ⟶ 1,394:
=={{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),
Line 1,339 ⟶ 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:
 
<syntaxhighlight lang="racket">#lang racket
 
(define (≈ a b [tolerance 1e-9])
Line 1,408 ⟶ 1,491:
For example, in Raku, the sum of .1, .2, .3, & .4 is ''identically'' equal to 1.
 
<syntaxhighlight lang=perl6"raku" line>say 0.1 + 0.2 + 0.3 + 0.4 === 1.0000000000000000000000000000000000000000000000000000000000000000000000000; # True</syntaxhighlight>
 
It's also ''approximately'' equal to 1 but... ¯\_(ツ)_/¯
 
<syntaxhighlight lang=perl6"raku" line>for
100000000000000.01, 100000000000000.011,
100.01, 100.011,
Line 1,450 ⟶ 1,533:
 
=={{header|ReScript}}==
<syntaxhighlight lang="rescript">let approx_eq = (v1, v2, epsilon) => {
abs_float (v1 -. v2) < epsilon
}
Line 1,476 ⟶ 1,559:
 
The choosing of the number of decimal digits is performed via the REXX statement: &nbsp; '''numeric digits &nbsp; ''nnn'' '''
<syntaxhighlight lang="rexx">/*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. */
Line 1,552 ⟶ 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.
<syntaxhighlight lang="ruby">require "bigdecimal"
 
testvalues = [[100000000000000.01, 100000000000000.011],
Line 1,598 ⟶ 1,703:
 
=={{header|Rust}}==
<syntaxhighlight lang="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
Line 1,636 ⟶ 1,741:
{{Out}}Best seen running in your browser by [https://scastie.scala-lang.org/kxD9xQuIQEGpABXnsE6BiQ Scastie (remote JVM)].
 
<syntaxhighlight lang=Scala"scala">object Approximate extends App {
val (ok, notOk, ε) = ("👌", "❌", 1e-18d)
 
Line 1,659 ⟶ 1,764:
=={{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.
<syntaxhighlight lang="ruby">[
100000000000000.01, 100000000000000.011,
100.01, 100.011,
Line 1,693 ⟶ 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.
 
<syntaxhighlight lang="ruby">var a = 100000000000000.01
var b = 100000000000000.011
 
Line 1,702 ⟶ 1,807:
There is also the built-in '''approx_cmp(a, b, k)''' method, which is equivalent with '''a.round(k) <=> b.round(k)'''.
 
<syntaxhighlight lang="ruby">var a = 22/7
var b = Num.pi
 
Line 1,716 ⟶ 1,821:
Additionally, the '''rat_approx''' method can be used for computing a very good rational approximation to a given real value:
 
<syntaxhighlight lang="ruby">say (1.33333333.rat_approx == 4/3) # true
say (zeta(-5).rat_approx == -1/252) # true</syntaxhighlight>
 
Rational approximations illustrated for substrings of PI:
<syntaxhighlight lang="ruby">for k in (3..19) {
var r = Str(Num.pi).first(k)
say ("rat_approx(#{r}) = ", Num(r).rat_approx.as_frac)
Line 1,749 ⟶ 1,854:
There are slight differences in how this is named in the various dialects &sup1;. If required, you have to add a forwarding alias method to Number.
{{works with|Smalltalk/X}}
<syntaxhighlight lang="smalltalk">{ #(100000000000000.01 100000000000000.011) .
#(100.01 100.011) .
{10000000000000.001 / 10000.0 . 1000000000.0000001000} .
Line 1,775 ⟶ 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.
 
<syntaxhighlight lang="swift">import Foundation
 
extension FloatingPoint {
Line 1,858 ⟶ 1,963:
===Using decimal library===
Uses tcllib's decimal library. Using a tolerance of 9 significant digits.
<syntaxhighlight lang=Tcl"tcl">catch {namespace delete test_almost_equal_decimal} ;# Start with a clean namespace
 
namespace eval test_almost_equal_decimal {
Line 1,905 ⟶ 2,010:
 
===Using string manipulation===
<syntaxhighlight lang=Tcl"tcl">catch {namespace delete test_almost_equal_string} ;# Start with a clean namespace
 
namespace eval test_almost_equal_string {
Line 1,962 ⟶ 2,067:
=={{header|Visual Basic .NET}}==
{{trans|C#}}
<syntaxhighlight lang="vbnet">Imports System.Runtime.CompilerServices
 
Module Module1
Line 1,999 ⟶ 2,104:
 
=={{header|Wren}}==
<syntaxhighlight lang=ecmascript"wren">var tol = 1e-16
var pairs = [
[100000000000000.01, 100000000000000.011],
Line 2,031 ⟶ 2,136:
 
=={{header|XPL0}}==
<syntaxhighlight lang=XPL0"xpl0">func ApproxEqual(A, B); \Return 'true' if approximately equal
real A, B;
real Epsilon;
Line 2,068 ⟶ 2,173:
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 2,073 ⟶ 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.
<syntaxhighlight lang="zkl">testValues:=T(
T(100000000000000.01,100000000000000.011),
T(100.01, 100.011),
9,476

edits