Disallow (dis)equality with FP.nan/FP.init literals
so
so at so.so
Wed Apr 18 18:28:50 PDT 2012
On Thursday, 19 April 2012 at 00:50:09 UTC, bearophile wrote:
> This is an open enhancement request that I'll probably add to
> Bugzilla.
> The direct cause of it is a recent discussion in D.learn, but I
> and other people are aware of this problem for a lot of time.
>
>
> Since a lot of time D statically refuses the use of
> "classReference == null":
>
> // Program #1
> class Foo {}
> void main() {
> Foo f;
> assert(f == null);
> assert(f != null);
> }
>
>
> test.d(4): Error: use 'is' instead of '==' when comparing with
> null
> test.d(5): Error: use '!is' instead of '!=' when comparing with
> null
>
>
>
> A not expert D programmer sometimes compares a double with
> double.nan in a wrong way:
>
> http://forum.dlang.org/thread/mailman.1845.1334694574.4860.digitalmars-d-learn@puremagic.com#post-jmlhfr:2428cv:241:40digitalmars.com
>
> because someDouble == double.nan is always false:
>
>
> // Program #2
> import std.math: isNaN;
> void main() {
> double x = double.init;
> assert(x != double.nan);
> assert(x != double.init);
> assert(isNaN(x));
> assert(x is double.init);
> assert(x !is double.nan);
>
> double y = double.nan;
> assert(y != double.nan);
> assert(y != double.init);
> assert(isNaN(y));
> assert(y !is double.init);
> assert(y is double.nan);
> }
>
>
>
> I think there are three common wrong usage patterns of NaNs
> testing:
> 1) Test that x is equal to/different from nan using
> x==FP.nan/x!=FP.nan
> 2) Test that x is equal to/different from all NaNs using
> x==FP.nan/x!=FP.nan
> 3) Test that x is equal to/different from FP.init using
> x==FP.init/x!=FP.init
>
> The case 3 is a bit less important because the programmer
> already knows something about FP init, but it's wrong still.
>
> There are other wrong usages of NaNs but they are by more
> expert programmers, to I don't want to catch them (example:
> using "is" to test if x is equal to/different from all NaNs is
> a bug, because there are more than one NaN. But if the
> programmer uses "is" I assume he/she/shi knows enough about
> NaNs, so this is not flagged by the compiler).
>
> Currently this program compiles with no errors:
>
>
> // Program #3
> void main() {
> float x1 = float.nan;
> assert(x1 == float.nan);
> float x2 = 0.0;
> assert(x2 != float.nan);
> float x3 = float.init;
> assert(x3 == float.init);
> float x4 = 0.0;
> assert(x4 != float.init);
>
> double x5 = double.nan;
> assert(x5 == double.nan);
> double x6 = 0.0;
> assert(x6 != double.nan);
> double x7 = double.init;
> assert(x7 == double.init);
> double x8 = 0.0;
> assert(x8 != double.init);
>
> real x9 = real.nan;
> assert(x9 == real.nan);
> real x10 = 0.0;
> assert(x10 != real.nan);
> real x11 = real.init;
> assert(x11 == real.init);
> real x12 = 0.0;
> assert(x12 != real.init);
>
> enum double myNaN = double.nan;
> assert(myNaN == double.nan);
> }
>
>
>
> So I propose to statically disallow comparisons of Program #3,
> so it generates errors similar to:
>
> test.d(4): Error: comparison is always false. Use
> 'std.math.isNaN' to test for every kind of NaN or 'is
> float.nan' for this specific NaN
> test.d(6): Error: comparison is always true. Use
> '!std.math.isNaN' to test for every kind of NaN or '!is
> float.nan' for this specific NaN
> test.d(8): Error: comparison is always false. Use
> 'std.math.isNaN' to test for every kind of NaN or 'is
> float.init' for this specicif NaN
> ...
>
>
> Opinions, improvements, votes or critics are welcome.
>
> Bye,
> bearophile
Good idea.
But nothing beats this:
int main() {
double q;
q = 3.0/7.0;
if (q == 3.0/7.0) printf("Equal\n");
else printf("Not Equal\n");
return 0;
}
http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html
Should we disable implicit conversion "at" comparison as well?
More information about the Digitalmars-d
mailing list