Jump to page: 1 2
Thread overview
[Issue 13489] Boolean semantics of floating point types should use "<> 0"
Sep 17, 2014
David Eckardt
Sep 18, 2014
Andrej Mitrovic
Sep 25, 2014
Walter Bright
Sep 25, 2014
Ketmar Dark
Sep 25, 2014
Leandro Lucarella
Sep 25, 2014
Leandro Lucarella
Sep 26, 2014
yebblies
Sep 26, 2014
David Eckardt
Sep 26, 2014
Leandro Lucarella
Oct 05, 2014
Walter Bright
Oct 09, 2014
Don
Oct 09, 2014
Dicebot
Mar 17, 2016
Stewart Gordon
Aug 27, 2019
Dlang Bot
Sep 01, 2019
Mathias LANG
September 17, 2014
https://issues.dlang.org/show_bug.cgi?id=13489

David Eckardt <david.eckardt@sociomantic.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |industry

--
September 18, 2014
https://issues.dlang.org/show_bug.cgi?id=13489

Andrej Mitrovic <andrej.mitrovich@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |andrej.mitrovich@gmail.com

--- Comment #1 from Andrej Mitrovic <andrej.mitrovich@gmail.com> ---
Also important to note is how easy a refactoring could produce invalid code. If you use integers in your code and if statements, and you decide to switch to floating-point (say to represent a fraction of a second for a time variable) you can easily end up with faulty code like that.

--
September 25, 2014
https://issues.dlang.org/show_bug.cgi?id=13489

Walter Bright <bugzilla@digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |bugzilla@digitalmars.com

--- Comment #2 from Walter Bright <bugzilla@digitalmars.com> ---
Consider this C++ code:

  bool foo(long double a) { return a; }

DMC++ generates:

                fld     tbyte ptr 4[ESP]
                fldz
                fucompp ST(1),ST
                fstsw   AX
                sahf
                jne     L13
                jp      L13
                xor     EAX,EAX
                jmp short       L18
    L13:        mov     EAX,1
    L18:        ret

and g++ generates:

                fld     tbyte ptr 8[RSP]
                mov     EAX,1
                fldz
                fucomip
                fstp    ST
                setp    DL
                cmovz   EAX,DL
                ret

In other words, both of them treat NaN as "TRUE". I fear that if we deviate from this behavior, we'll get subtly broken code that is written by former C++ programmers or that is transliterated from C++.

Having cast(bool)d yield different results than d!=0 to me is very surprising
behavior.

Having cast(bool)d rewritten to be d<>0 is also problematic as Don Clugston is a vocal advocate of having the <> operator removed from D.

Issuing a warning or error for if(d) can be done, but then the user simply
rewrites it as if(d!=0) and I'm not sure if anything was accomplished.

So I'm not sure what the right answer would be.

I do strongly suggest that calculations that return money values have sanity checks in them for reasonable dollar values; not just 0, Infinity or NaN checks. An amount of 9 trillion dollars shouldn't have gotten far. Such checks can find a great many more mistakes than NaNs would.

Another possibility is to not use lround(), i.e. make your own lround that asserts that its argument is not NaN. Note that lround() in D just defers to the C one, which is underspecified as to what happens with NaN or Infinity arguments. I would not rely on C's lround() for financial calculations without first checking its argument.

--
September 25, 2014
https://issues.dlang.org/show_bug.cgi?id=13489

Ketmar Dark <ketmar@ketmar.no-ip.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |ketmar@ketmar.no-ip.org

--- Comment #3 from Ketmar Dark <ketmar@ketmar.no-ip.org> ---
(In reply to Walter Bright from comment #2)
> Having cast(bool)d yield different results than d!=0 to me is very
> surprising behavior.
for me too. NaN is clearly not 0, so it's 'true'.

but maybe compiler should produce warning telling programmer that he is about
to summon a dragon? i.e. for implicit converts to boolean, like `if (d)` and
`assert(d)` compiler will tell that "implicit convertsion of double to boolean
leads to undesired results, please use explicit cast(bool)".

as for '!=' vs '<>'... i don't know. it's easy to emit a warning, but i can't think out sane method to hush the compiler if "!=" is what i really want.

--
September 25, 2014
https://issues.dlang.org/show_bug.cgi?id=13489

bearophile_hugs@eml.cc changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |bearophile_hugs@eml.cc

--- Comment #4 from bearophile_hugs@eml.cc ---
The current D situation seems standard:

http://stackoverflow.com/questions/9158567/nan-to-bool-conversion-true-or-false

http://stackoverflow.com/questions/15686318/why-do-not-a-number-values-equal-true-when-cast-as-boolean-in-python-numpy

--
September 25, 2014
https://issues.dlang.org/show_bug.cgi?id=13489

Leandro Lucarella <leandro.lucarella@sociomantic.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |leandro.lucarella@sociomant
                   |                            |ic.com

--- Comment #5 from Leandro Lucarella <leandro.lucarella@sociomantic.com> ---
What the relation of signaling NaN and this. Will `if (nan)` raise a signal? Maybe a runtime check is enough.

It's clear that the code that raise this problem is buggy, no argue about that, but how to fix it is not the topic of this issue, the topic is trying to find a way to make the bug impossible to even exist, with help from the language :)

--
September 25, 2014
https://issues.dlang.org/show_bug.cgi?id=13489

--- Comment #6 from Leandro Lucarella <leandro.lucarella@sociomantic.com> ---
(In reply to Leandro Lucarella from comment #5)
> What the relation of signaling NaN and this. Will `if (nan)` raise a signal?

Or any following use of nan afterwards, like `lround(fabs(x))`.

f the
> Maybe a runtime check is enough.
> 
> It's clear that the code that raise this problem is buggy, no argue about that, but how to fix it is not the topic of this issue, the topic is trying to find a way to make the bug impossible to even exist, with help from the language :)

--
September 26, 2014
https://issues.dlang.org/show_bug.cgi?id=13489

yebblies <yebblies@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |yebblies@gmail.com

--- Comment #7 from yebblies <yebblies@gmail.com> ---
(In reply to Walter Bright from comment #2)
> Having cast(bool)d rewritten to be d<>0 is also problematic as Don Clugston is a vocal advocate of having the <> operator removed from D.

This is not problematic, the compiler using it internally does not mean it has to be exposed to the user.

--
September 26, 2014
https://issues.dlang.org/show_bug.cgi?id=13489

--- Comment #8 from David Eckardt <david.eckardt@sociomantic.com> ---
> I do strongly suggest that calculations that return money values have sanity checks in them for reasonable dollar values; not just 0, Infinity or NaN checks.

Absolutely. It was just an impressing situation where NaN caught me. I don't blame D for not catching this particular bug, and I'm aware there are alternative ways of detecting this bug.

My point is: NaN was intentionally chosen as the initial floating point value
to detect the common bug of forgetting to initialize a variable
(http://dlang.org/faq.html#nan). The standard way to detect bugs is a plain
assert(). So assert() should fail with NaN.
I suggest the boolean behaviour of <>0 because believe it makes more sense in
general, is compatible to !=0 for integers and pointers and would make assert()
fail with NaN.

> Having cast(bool)d yield different results than d!=0 to me is very
> surprising behavior.

I agree it can be considered surprising, and that's an essential point of this debate. But at least if d is a negative 0, cast(bool)d is false even though the binary data in d contain a set bit (i.e., if d is a double, cast(bool)*cast(ulong*)&d is true). This can be considered surprising, too. On the other hand, by its nature NaN causes many surprises so I believe we can live with a false boolean result if we have the benefit of catching a well known bug.

(PS. Amounts like 80,833,756,980 Vietnamese Đồng do happen so limiting them is far from trivial...)

--
September 26, 2014
https://issues.dlang.org/show_bug.cgi?id=13489

--- Comment #9 from Leandro Lucarella <leandro.lucarella@sociomantic.com> ---
(In reply to David Eckardt from comment #8)
> My point is: NaN was intentionally chosen as the initial floating point
> value to detect the common bug of forgetting to initialize a variable
> (http://dlang.org/faq.html#nan). The standard way to detect bugs is a plain
> assert(). So assert() should fail with NaN.

Yeah, this is the key, NaN should behave the same as null, it should explode as soon as it's used.

> (PS. Amounts like 80,833,756,980 Vietnamese Đồng do happen so limiting them is far from trivial...)

Yeah, you should have to check the currency and maintain a table of conversion rates. Not a very promising approach ;-)

--
« First   ‹ Prev
1 2