September 17, 2014 [Issue 13489] New: Boolean semantics of floating point types should use "<> 0" | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=13489 Issue ID: 13489 Summary: Boolean semantics of floating point types should use "<> 0" Product: D Version: D1 & D2 Hardware: All OS: All Status: NEW Severity: enhancement Priority: P1 Component: DMD Assignee: nobody@puremagic.com Reporter: david.eckardt@sociomantic.com Floating point numbers can be implicitly cast to bool so they can be used as if() and assert() arguments. In this case NaN evaluates to true. I'm working at Sociomantic where this behaviour didn't reveal a bug and caused us to attempt to spend a monetary amount of $9223372036854.775808: --- import stdc.math: lround, fabs; ulong calcAmount ( double x ) in { assert(x); // succeeds for NaN } body { // do calculation with x return lround(fabs(x)); // returns 9223372036854775808 if x is NaN } --- It happens because currently for a floating point variable x "cast(bool)x" behaves like "(x != 0)". I suggest changing that to "(x <> 0)". Rationale: The difference between "!=" and "<>" is subtle, many programmers aren't aware of it, and even the ones who are do this mistake easily, as it happened to me. "x != 0" is appropriate for integer and pointer types. For floating point types one has always to respect NaN, and "!=" doesn't do that so, unless NaN is anticipated, one should use "<>" instead. This applies in most use cases and, since it is the initial floating point value, NaN is encountered mostly caused by a bug of using a variable without assigning it before. This very notorious bug should be detected by "assert(x)", and I'd be surprised if most existing code that does "if (x)" (or otherwise uses floating point values as boolean) works as it should with NaN. -- |
Copyright © 1999-2021 by the D Language Foundation