Bug 13663 – Comparison of Tuples with floating point fields
Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P1
Component
phobos
Product
D
Version
D2
Platform
x86_64
OS
Windows
Creation time
2014-10-29T09:26:53Z
Last change time
2021-01-19T15:38:08Z
Keywords
pull
Assigned to
No Owner
Creator
Ryuichi OHORI
Comments
Comment #0 by r.97all — 2014-10-29T09:26:53Z
A Tuple with only component nan is greater than itself.
unittest
{
import std.typecons;
real x;
auto t = tuple(x);
assert (t > t);
assert (!(t < t));
}
Comment #1 by peter.alexander.au — 2014-12-14T21:17:23Z
There is nothing that can be done here. For user defined types (e.g. Tuple), comparison operators are converted to calls to opCmp, i.e.
a < b a.opCmp(b) < 0
a <= b a.opCmp(b) <= 0
a > b a.opCmp(b) > 0
a >= b a.opCmp(b) >= 0
For NaN vs NaN, the comparison is neither equal, less than, nor greater than. There is nothing that opCmp can return to give the desired semantics.
Comment #2 by bugzilla — 2019-12-04T06:14:09Z
I cannot even see a place, where this can be clearified in the docs. Maybe in some very general place, like some page on floating point numbers in general.
Comment #3 by simen.kjaras — 2019-12-04T07:46:06Z
Peter's claims in comment 1 are plain false - opCmp can return float, and float.nan for incomparable cases. Here's an implementation of opCmp that does that:
float opCmp(R)(R rhs)
if (areCompatibleTuples!(typeof(this), R, "<"))
{
static foreach (i; 0 .. Types.length)
{
if (field[i] != field[i] || rhs.field[i] != rhs.field[i])
{
return float.nan;
}
if (field[i] != rhs.field[i])
{
return field[i] < rhs.field[i] ? -1 : 1;
}
}
return 0;
}
/// ditto
float opCmp(R)(R rhs) const
if (areCompatibleTuples!(typeof(this), R, "<"))
{
static foreach (i; 0 .. Types.length)
{
if (field[i] != field[i] || rhs.field[i] != rhs.field[i])
{
return float.nan;
}
if (field[i] != rhs.field[i])
{
return field[i] < rhs.field[i] ? -1 : 1;
}
}
return 0;
}
These are taken directly from std.typecons, and the only change made is they return float, and check if any of the fields are incomparable.
Comment #4 by bugzilla — 2019-12-04T11:18:30Z
(In reply to Simen Kjaeraas from comment #3)
> opCmp can return float
Oh, I didn't know that trick with returning nan. I'll check your solution and add a PR.
Comment #5 by dlang-bot — 2019-12-04T11:54:32Z
@berni44 created dlang/phobos pull request #7301 "Fix Issue 13663 - Comparison of Tuples with floating point fields" fixing this issue:
- Fix Issue 13663 - Comparison of Tuples with floating point fields
https://github.com/dlang/phobos/pull/7301
Comment #6 by bugzilla — 2019-12-21T09:21:38Z
*** Issue 18832 has been marked as a duplicate of this issue. ***
Comment #7 by dlang-bot — 2021-01-17T18:12:47Z
@berni44 created dlang/phobos pull request #7748 "Fix Issue 13663 - Comparison of Tuples with floating point fields" fixing this issue:
- Fix Issue 13663 - Comparison of Tuples with floating point fields
https://github.com/dlang/phobos/pull/7748
Comment #8 by dlang-bot — 2021-01-19T15:38:08Z
dlang/phobos pull request #7748 "Fix Issue 13663 - Comparison of Tuples with floating point fields" was merged into master:
- ab2f7cdef4d80964a85440699b358fb95b50b26f by Bernhard Seckinger:
Fix Issue 13663 - Comparison of Tuples with floating point fields
https://github.com/dlang/phobos/pull/7748