C++ Logo

std-proposals

Advanced search

Re: new approximately equal operators

From: Jake Arkinstall <jake.arkinstall_at_[hidden]>
Date: Tue, 9 Jun 2020 00:14:34 +0100
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_at_[hidden]> 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_at_[hidden]> 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_at_[hidden]> 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_at_[hidden]
>>> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>>>
>> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>

Received on 2020-06-08 18:17:51