www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Is D floating point semantics too advanced?

reply =?ISO-8859-1?Q?Hans-Eric_Gr=f6nlund?= <hasse42g gmail.com> writes:
Hello!

I've written a post on my blog wondering if the floating point semantics is too
advanced. The problem I have with it is that I can't write something like this:

if (someValue == real.nan) {...}

It will never be true, which - for me - is unintuitive.

The post is at http://www.hans-eric.com/2007/08/23/is-floating-point-handling-too-advanced-in-d/
and I'd love to get some comments.

Best regards

Hans-Eric Grönlund
Software Developer, Project Manager, Freelance Journalist
www.hans-eric.com
Aug 23 2007
next sibling parent reply Oskar Linde <oskar.lindeREM OVEgmail.com> writes:
Hans-Eric Grönlund skrev:
 Hello!
 
 I've written a post on my blog wondering if the floating point semantics is
too advanced. The problem I have with it is that I can't write something like
this:
 
 if (someValue == real.nan) {...}
 
 It will never be true, which - for me - is unintuitive.

And for others, the opposite would be unintuitive. A classic test for NaN is if (x != x) {...} There are several reasons for the current behavior, and one of them is that this behavior is what a ieee 754 allows. There are a very large number of different binary representations of floating point numbers that represent NaN. Out of habit, I usually use isnan(x) to explicitly check for NaN, but x !<>= 0 should work as well. I agree that the multitude of floating point comparison operators can feel overwhelming, and I often have to check the table to be sure, but they are very logical if you remember that NaN always compare false with the non-negated operators: <, <=, ==, >=, >, <>, <>=, and therefore compare true with their opposites: !<, !<=, !=, !>=, !>, !<>, !<>=. -- Oskar
Aug 23 2007
parent =?ISO-8859-1?Q?Hans-Eric_Gr=f6nlund?= <hasse42g gmail.com> writes:
Thank you, your comment helped me to better understand the rationale behind
this behavior.

One reflection: I've been in this business for almost two decades, and I have
never come across the "classic test for NaN". Not that I would have recognized
it though - it doesn't look like such a test. The behavior is not consistent
with that of the other numerical types (there is no special "uninitialized"
value for integer types, although maybe there should be one...). Anyway, I
guess all this just shows how little floating point programming I've had to do
so far :-)

Hans-Eric

Oskar Linde Wrote:

 Hans-Eric Grönlund skrev:
 Hello!
 
 I've written a post on my blog wondering if the floating point semantics is
too advanced. The problem I have with it is that I can't write something like
this:
 
 if (someValue == real.nan) {...}
 
 It will never be true, which - for me - is unintuitive.

And for others, the opposite would be unintuitive. A classic test for NaN is if (x != x) {...} There are several reasons for the current behavior, and one of them is that this behavior is what a ieee 754 allows. There are a very large number of different binary representations of floating point numbers that represent NaN. Out of habit, I usually use isnan(x) to explicitly check for NaN, but x !<>= 0 should work as well. I agree that the multitude of floating point comparison operators can feel overwhelming, and I often have to check the table to be sure, but they are very logical if you remember that NaN always compare false with the non-negated operators: <, <=, ==, >=, >, <>, <>=, and therefore compare true with their opposites: !<, !<=, !=, !>=, !>, !<>, !<>=. -- Oskar

Aug 23 2007
prev sibling next sibling parent reply Walter Bright <newshound1 digitalmars.com> writes:
Hans-Eric Grönlund wrote:
 I've written a post on my blog wondering if the floating point
 semantics is too advanced. The problem I have with it is that I can't
 write something like this:
 
 if (someValue == real.nan) {...}
 
 It will never be true, which - for me - is unintuitive.

The behavior is as specified by the floating point standard IEEE 754. To change it would break from FORTRAN, C and C++ usage in a way that would silently break code that is transliterated.
Aug 23 2007
next sibling parent reply =?ISO-8859-1?Q?Hans-Eric_Gr=f6nlund?= <hasse42g gmail.com> writes:
Point taken. Still feel awkward about having to accept tests like (x != x) with
hidden (not obvious) semantics, special for floating point types. But I shall
not hold D responsible for it anymore, this is a matter of the standard
specification.

Thank you for enlightening me.

/Hans-Eric

Walter Bright Wrote:

 The behavior is as specified by the floating point standard IEEE 754. To 
 change it would break from FORTRAN, C and C++ usage in a way that would 
 silently break code that is transliterated.

Aug 24 2007
parent Walter Bright <newshound1 digitalmars.com> writes:
Hans-Eric Grönlund wrote:
 Point taken. Still feel awkward about having to accept tests like (x
 != x) with hidden (not obvious) semantics, special for floating point
 types. But I shall not hold D responsible for it anymore, this is a
 matter of the standard specification.
 
 Thank you for enlightening me.

No prob, I don't really understand why this is the convention myself.
Aug 25 2007
prev sibling parent reply Sean Kelly <sean f4.ca> writes:
Walter Bright wrote:
 Hans-Eric Grönlund wrote:
 I've written a post on my blog wondering if the floating point
 semantics is too advanced. The problem I have with it is that I can't
 write something like this:

 if (someValue == real.nan) {...}

 It will never be true, which - for me - is unintuitive.

The behavior is as specified by the floating point standard IEEE 754. To change it would break from FORTRAN, C and C++ usage in a way that would silently break code that is transliterated.

It would be a horrible inconsistency, but the 'is' operator could be made to return true in this instance. After all, 'is' tests identity, not equality. Sean
Aug 26 2007
next sibling parent Walter Bright <newshound1 digitalmars.com> writes:
Sean Kelly wrote:
 The behavior is as specified by the floating point standard IEEE 754. 
 To change it would break from FORTRAN, C and C++ usage in a way that 
 would silently break code that is transliterated.

It would be a horrible inconsistency, but the 'is' operator could be made to return true in this instance. After all, 'is' tests identity, not equality.

I'd prefer sticking with isnan(). It's what the numerics guys are used to.
Aug 26 2007
prev sibling parent reply Bruno Medeiros <brunodomedeiros+spam com.gmail> writes:
Sean Kelly wrote:
 Walter Bright wrote:
 Hans-Eric Grönlund wrote:
 I've written a post on my blog wondering if the floating point
 semantics is too advanced. The problem I have with it is that I can't
 write something like this:

 if (someValue == real.nan) {...}

 It will never be true, which - for me - is unintuitive.

The behavior is as specified by the floating point standard IEEE 754. To change it would break from FORTRAN, C and C++ usage in a way that would silently break code that is transliterated.

It would be a horrible inconsistency, but the 'is' operator could be made to return true in this instance. After all, 'is' tests identity, not equality. Sean

Why would it be inconsistent? Because the equality contract states that anything that has the same identity, should also compare equal? -- Bruno Medeiros - MSc in CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
Aug 26 2007
parent Sean Kelly <sean f4.ca> writes:
Bruno Medeiros wrote:
 Sean Kelly wrote:
 Walter Bright wrote:
 Hans-Eric Grönlund wrote:
 I've written a post on my blog wondering if the floating point
 semantics is too advanced. The problem I have with it is that I can't
 write something like this:

 if (someValue == real.nan) {...}

 It will never be true, which - for me - is unintuitive.

The behavior is as specified by the floating point standard IEEE 754. To change it would break from FORTRAN, C and C++ usage in a way that would silently break code that is transliterated.

It would be a horrible inconsistency, but the 'is' operator could be made to return true in this instance. After all, 'is' tests identity, not equality.

Why would it be inconsistent? Because the equality contract states that anything that has the same identity, should also compare equal?

I think it's easier to simply remember that 'is' compares identity for references and equality everywhere else. It would be easy to forget or screw up the special treatment of floating point numbers, particularly in template code. I suggested using it more because it makes conceptual sense than because it seemed practical to me. Sean
Aug 26 2007
prev sibling next sibling parent davidl <davidl 126.com> writes:
在 Thu, 23 Aug 2007 22:45:32 +0800,Hans-Eric Grönlund  
<hasse42g gmail.com> 写道:

 Hello!

 I've written a post on my blog wondering if the floating point semantics  
 is too advanced. The problem I have with it is that I can't write  
 something like this:

 if (someValue == real.nan) {...}

Compiler should emit error messages(or warning?) of comparing with NAN for compile time constants And the runtime NAN would leave to runtime to determine ( this is well defined in IEEE I think) For compile time stuff, since it's result is *fixed*. So such code should at least be warned or something. or some compiler option -W-floatnan?
 It will never be true, which - for me - is unintuitive.

 The post is at  
 http://www.hans-eric.com/2007/08/23/is-floating-point-handling-too-advanced-in-d/
 and I'd love to get some comments.

 Best regards

 Hans-Eric Grönlund
 Software Developer, Project Manager, Freelance Journalist
 www.hans-eric.com

-- 使用 Opera 革命性的电子邮件客户程序: http://www.opera.com/mail/
Aug 23 2007
prev sibling parent reply Lars Noschinski <lars-2006-1 usenet.noschinski.de> writes:
* Hans-Eric Grönlund <hasse42g gmail.com> [07-08-23 16:45]:
Hello!

I've written a post on my blog wondering if the floating point semantics is too
advanced. The problem I have with it is that I can't write something like this:

if (someValue == real.nan) {...}

In this case it seems unintuitive because you use NaN explicitly on the right side. But you'd probably be surprised to see 0.0/0.0 == sqrt(-1.L) evaluating to true.
Aug 24 2007
parent =?ISO-8859-1?Q?Hans-Eric_Gr=f6nlund?= <hasse42g gmail.com> writes:
Finally a convincing reason for the behavior. I also realized, when reading up
on the IEEE 754 specification, that NaN was not necessarily represented as one
value, but could be a whole family of values. That complicates things further.

I hereby drop my case!

Thank you all for your comments!

Lars Noschinski Wrote:

 * Hans-Eric Grönlund <hasse42g gmail.com> [07-08-23 16:45]:
Hello!

I've written a post on my blog wondering if the floating point semantics is too
advanced. The problem I have with it is that I can't write something like this:

if (someValue == real.nan) {...}

In this case it seems unintuitive because you use NaN explicitly on the right side. But you'd probably be surprised to see 0.0/0.0 == sqrt(-1.L) evaluating to true.

Aug 24 2007