On Tuesday, 12 November 2013 at 16:48:01 UTC, Andrei Alexandrescu wrote:
On 11/12/13 8:00 AM, Vladimir Panteleev wrote:
1) NaN values are accepted as input almost anywhere where doubles are. std.conv recognizes the string "nan" and converts it to double.nan,

They are still singular values. Code has no business comparing them unwittingly.

2) It is unreasonable to expect every D user out there dealing with floating point numbers to be forced to check every source of floating
point values in their program against NaNs.

I find that perfectly reasonable. How do you mean that?

Both of the above hinge on the relative obscurity of NaNs and the problems they could cause. People who are not specifically familiar with NaNs and how they interact with other floating-point values will treat floating-point values as "just numbers", and expect them to compare and sort in the same way as integers.

The language allows NaN floating point number with the semantics of IEEE 754. We hardly have any leeway in the matter unless we want to irate a lot of people for no good reason.

It's a judgment call, not a cut and dried decision.

Agreed - however, I think there might be more than one way to deal with this.

1) As above, introduce a "less" function which guarantees transitivity for basic types, and use it in examples throughout.

2) Improve documentation and visibility of this problem. For example, add this to the documentation of sort:

"The predicate must be transitive (`a<b && b<c` implies `a<c`) in order for `sort` to behave properly - otherwise, the program may fail on certain inputs (but not others) when not compiled in release mode. Note that `a<b` is not transitive for floating points, because the expression will always be `false` when either `a` or `b` is `NaN`."

We should simply add an assert to isSorted.

How would this be implemented, anyway? I stumbled upon this problem with this code:

enum sortPred = q{a.hits > b.hits || (a.hits == b.hits && a.value < b.value)};
all.sort!sortPred();

(I know about multiSort, but it currently seems to be buggy - I do have a test case, but it has a few million entries and I need to reduce it.)

if (a[i] < a[i + 1]) { assert(!(a[i + 1] < a[i])); ... }
else { assert(a[i + 1] >= a[i]); ... }

Sort et al don't know how to check "a>=b"... and they can't use "a<b" either, because !(a<b) && !(b<a) implies a==b.

Reply via email to