Thread overview
Overloading float operators
Dec 11, 2017
rumbu
Dec 11, 2017
ag0aep6g
Dec 11, 2017
Jonathan M Davis
December 11, 2017
Is there any way to overload specific floating point operators?
https://dlang.org/spec/expression.html#floating-point-comparisons

I'm using a decimal data type (a struct) and one of the possible values is NaN, that's why I need these operators.

I know also that this also was discussed, but is there any way to separately implement == and !=, so both return true or false in the same time?

The reason is the same: NaN == NaN = false and NaN != NaN = false in the same time.

December 11, 2017
On 12/11/2017 08:28 PM, rumbu wrote:
> Is there any way to overload specific floating point operators?
> https://dlang.org/spec/expression.html#floating-point-comparisons

Those don't seem to work anymore. At least since 2.073, dmd rejects them and says to use std.math.isNaN instead. Looks like someone forgot to upate the spec. I couldn't find anything in the changelog either.

> I'm using a decimal data type (a struct) and one of the possible values is NaN, that's why I need these operators.

You can return float.nan from opCmp to mean "unordered":

----
struct S
{
    bool isNaN = true;
    int value;

    this(int value) { this.isNaN = false; this.value = value; }

    bool opEquals(const S other) const pure nothrow @safe @nogc
    {
        return !this.isNaN && !other.isNaN && this.value == other.value;
    }

    float opCmp(const S other) const pure nothrow @safe @nogc
    {
        if (this.isNaN || other.isNaN) return float.nan;
        if (this.value < other.value) return -1;
        if (this.value > other.value) return 1;
        return 0;
    }
}

void main()
{
    S s1; // NaN
    S s2; // NaN

    assert(s1 != s2); // neither equal ...
    assert(!(s1 < s2)); // nor less than ...
    assert(!(s1 > s2)); // nor greater
}
----

> I know also that this also was discussed, but is there any way to separately implement == and !=, so both return true or false in the same time?

I don't think so.

> The reason is the same: NaN == NaN = false and NaN != NaN = false in the same time.

But NaN != NaN is true.
December 11, 2017
On Monday, December 11, 2017 19:28:47 rumbu via Digitalmars-d-learn wrote:
> Is there any way to overload specific floating point operators? https://dlang.org/spec/expression.html#floating-point-comparisons

If those haven't been deprecated yet, they almost certainly will be. It was decided that they were a mistake, and AFAIK, pretty much no one uses them. opEquals and opCmp are all that there is for overloading comparison operators.

> I'm using a decimal data type (a struct) and one of the possible values is NaN, that's why I need these operators.
>
> I know also that this also was discussed, but is there any way to separately implement == and !=, so both return true or false in the same time?
>
> The reason is the same: NaN == NaN = false and NaN != NaN = false in the same time.

You cannot overload == and != separately, but why would you need to? There's
no reason for a != b to not be the same as !(a == b) even with floating
point
comparisons. e.g.

import std.stdio;

void main()
{
    float f;
    writeln(f == f);
    writeln(f != f);
}

prints

false
true

- Jonathan M Davis