I've worked approximations a lot, and honestly I don't think a language solution makes sense given how many forms of approximation there are.

For example, with a std::complex<double>, you might have different constraints on the allowable real and imaginary components. You might instead have constraints on the angle and the magnitude. It's context-dependent. For vectors and arrays, you have the same deal.


For a double, you might want a maximum discrepancy in absolute terms, or percentage terms.

There is an argument for approximations in datetimes, integers, bitsets, strings - if there's a type for it, there's probably an entire community that consider two distinct values approximately equal. As such, you want to provide them with customisation points, a flexible interface, and syntax that doesn't break the principle of least astonishment. I'm afraid "x ~= y(0.1)" violates that by having the operator tuning parameter applied to an argument.

The Catch2 testing library (https://github.com/catchorg/Catch2/blob/master/docs/assertions.md) does a nice job of providing floating point comparisons in a customisable way. For simple comparisons you can use "x = Approx(y)". Approx is actually a class so you can tune it via "x = Approx(y).epsilon(0.1)", or store a tuned approximation for later use.

Id recommend looking down that route to begin with. Making something more extensible to more general types would be a good start, and as long as there's a sensible interface for simple cases then I don't see why it wouldn't be accepted as an addition to the standard library.


On Mon, 8 Jun 2020, 23:28 Vishal Oza via Std-Proposals, <std-proposals@lists.isocpp.org> wrote:
for you questions
  1. epsilon would be a very small number close to zero but not zero. Having epsilon as a variable might not be needed in there is a way to track the accuracy of floating point error over the course of the calculation to the operator.or we might be about to use the exponent to compute what  epsilon value seem reasonable
  2. yes it can be but it is extra pointless work the only reason I use abs(a-b) is to remove the sign is the number is negative.  It might also this to work with complex number but I this I would have to explore this further.
  3. assignment of ~= does not compile in current C++ but  in what I propose a ~= 5000(0.1) would translate to abs(a-5000) < 0.1  
also the == would be very unreadable according to your logic.
int f = 5000;
float x = 0.1;
auto a == f(x);

then what about:

int caruso(int a);

auto a == caruzo(f)(x);
or...
auto a == ( caruzo(f) )(x);

 

On Mon, Jun 8, 2020 at 3:06 PM Nikolay Mihaylov <nmmm@nmmm.nu> wrote:
1. What is epsilon?
2. didn't this abs(a-b) be abs(abs(a)-abs(b))
3. a ~=b(c)  - b(c)   this actually will be:

auto a ~= 5000(0.1);

is very unreadable.
int f = 5000;
float x = 0.1;
auto a ~= f(x);

then what about:

int caruso(int a);

auto a ~= caruzo(f)(x);
or...
auto a ~= ( caruzo(f) )(x);




On Mon, Jun 8, 2020 at 10:55 PM Vishal Oza via Std-Proposals <std-proposals@lists.isocpp.org> wrote:
I was wondering if there is any interest in adding approximately equal to operators into the language. The main purpose is to compare floating point calculations with rounding error, however they could be used for similarity of objects or fixed point rounded values as well.

the operator I propose are: ~=, ~< , ~>, ~! 
these operators would translate at least to floating point as
a ~= b ==> abs(a-b) <  epsilon
a ~< b ==> (a < b) || (abs(a-b) <  epsilon)
 a ~> b ==> (a > b) || (abs(a-b) <  epsilon)
a ~! b ==> abs(a-b) >=   epsilon
  
There are two routes I can see with default implementation this language feature. either adding a default epsilon into the language that can be set as a global variable or adding some way of tracking errors. I would like more feedback on either way of default implementation.

I would also like a way to specify the epsilon value or function for a single comparison. the best I can think of is
a ~=b(c) ==>  abs(a-b) <  c 
a ~=b:c ==>  abs(a-b) <  c 
[c]a ~=b ==>  abs(a-b) <  c 

The precedence should be on the same level of all of the current comparison operators.

This could be introduced in C++ 23 or later in there is any interate.

Sincerely,
Vishal Oza 
--
Std-Proposals mailing list
Std-Proposals@lists.isocpp.org
https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
--
Std-Proposals mailing list
Std-Proposals@lists.isocpp.org
https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals