D - Floating Point RelOps

• samwyse (9/21) Oct 09 2001 to this:
• Walter (4/25) Oct 09 2001 The former is correct. != does not mean !(==) when dealing with NaNs. Ye...
• Russ Lewis (23/23) Oct 09 2001
• Walter (8/31) Oct 09 2001 both
• Ben Cohen (3/9) Oct 10 2001 What about throwing a NANException instead?
• Walter (4/11) Oct 10 2001 It already does raise a sticky flag in the 8087 status word which you ca...
• Ben Cohen (21/33) Oct 11 2001 Yes, the compiler can read that. But the programmer isn't automatically
• Walter (8/41) Oct 11 2001 I think throwing an exception on NAN would be more annoying to the
• Sean L. Palmer (9/13) Oct 23 2001 Personally I'd prefer if floats get initialized to zero, like the ints a...
samwyse <sdenton wantec.com> writes:
```Am I misreading something, or is there a contradiction in the specs?
Compare this:

Equality for floating point types is more complicated. -0 and +0

compare as equal. If either or both operands are NAN, then both the

== and != comparisons return false. Otherwise, the bit patterns are

compared for equality.

to this:

Useful floating point operations must take into account NAN values.

In particular, a relational operator can have NAN operands. The result

of a relational operation on float values is less, greater, equal, or

unordered (unordered means either or both of the operands is a NAN).

That means there are 14 possible comparison conditions to test for:
[...]
!= unordered, less, or greater
[...]

The first says quite plainly that "5 != NAN" returns "false", but the
second (if I'm understanding the meaning of "unordered") indicates that
"5 != NAN" should return "true".

At the risk of confusing C programmers, I'd say go with the second
interpretation.  Also, the rel-ops containing "!" should only be allowed
with floating point values.  For int, pointers, etc, use "<>" instead.
```
Oct 09 2001
"Walter" <walter digitalmars.com> writes:
```The former is correct. != does not mean !(==) when dealing with NaNs. Yes, I
know it's confusing! -Walter

"samwyse" <sdenton wantec.com> wrote in message
news:3BC37E64.9070401 wantec.com...
Am I misreading something, or is there a contradiction in the specs?
Compare this:

Equality for floating point types is more complicated. -0 and +0

> compare as equal. If either or both operands are NAN, then both the

== and != comparisons return false. Otherwise, the bit patterns are

compared for equality.

to this:

Useful floating point operations must take into account NAN values.

In particular, a relational operator can have NAN operands. The result

of a relational operation on float values is less, greater, equal, or

unordered (unordered means either or both of the operands is a NAN).

That means there are 14 possible comparison conditions to test for:
[...]
!= unordered, less, or greater
[...]

The first says quite plainly that "5 != NAN" returns "false", but the
second (if I'm understanding the meaning of "unordered") indicates that
"5 != NAN" should return "true".

At the risk of confusing C programmers, I'd say go with the second
interpretation.  Also, the rel-ops containing "!" should only be allowed
with floating point values.  For int, pointers, etc, use "<>" instead.

```
Oct 09 2001
Russ Lewis <spamhole-2001-07-16 deming-os.org> writes:
```<random-pondering>

Perhaps this suggests a 3-way boolean state?

true
false
unknown

if(), while(), for(), etc. only count it as true if it is actually true; both
'false' and 'unknown' cause them to fail.  The logical negation operator maps:
true->false
false->true
unknown->unknown

Any logical operations involving unknown also return unknown.

Big downside of a 3-way bool, ofc, is that it no longer fits in a bit...would
have to be 2 bits at least.  Anybody have any idea what a reasonable 4th boolean
state would be????

This gets us back to the question of whether bool is a separate type or if it's
just an integer.  If it's not an integer, we probably needs a bool.isUnknown
property or some such.

</random-pondering>

--
The Villagers are Online! http://villagersonline.com

.[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ]
.[ (a version.of(English).(precise.more)) is(possible) ]
?[ you want.to(help(develop(it))) ]
```
Oct 09 2001
"Walter" <walter digitalmars.com> writes:
```Oh, I don't want to revisit the 3 state boolean again !!

Russ Lewis wrote in message <3BC3AF00.779903EA deming-os.org>...
<random-pondering>

Perhaps this suggests a 3-way boolean state?

true
false
unknown

if(), while(), for(), etc. only count it as true if it is actually true;

both
'false' and 'unknown' cause them to fail.  The logical negation operator

maps:
true->false
false->true
unknown->unknown

Any logical operations involving unknown also return unknown.

Big downside of a 3-way bool, ofc, is that it no longer fits in a

bit...would
have to be 2 bits at least.  Anybody have any idea what a reasonable 4th

boolean
state would be????

This gets us back to the question of whether bool is a separate type or if

it's
just an integer.  If it's not an integer, we probably needs a

bool.isUnknown
property or some such.

</random-pondering>

--
The Villagers are Online! http://villagersonline.com

.[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ]
.[ (a version.of(English).(precise.more)) is(possible) ]
?[ you want.to(help(develop(it))) ]

```
Oct 09 2001
"Ben Cohen" <bc skygate.co.uk> writes:
```In article <9q0o9a\$gch\$1 digitaldaemon.com>, "Walter"
<walter digitalmars.com> wrote:

Oh, I don't want to revisit the 3 state boolean again !!

Russ Lewis wrote in message <3BC3AF00.779903EA deming-os.org>...
<random-pondering>

Perhaps this suggests a 3-way boolean state?

```
Oct 10 2001
"Walter" <walter digitalmars.com> writes:
```"Ben Cohen" <bc skygate.co.uk> wrote in message
news:9q10ok\$t2h\$1 digitaldaemon.com...
In article <9q0o9a\$gch\$1 digitaldaemon.com>, "Walter"
<walter digitalmars.com> wrote:
Oh, I don't want to revisit the 3 state boolean again !!
Russ Lewis wrote in message <3BC3AF00.779903EA deming-os.org>...
<random-pondering>
Perhaps this suggests a 3-way boolean state?

It already does raise a sticky flag in the 8087 status word which you can
```
Oct 10 2001
"Ben Cohen" <bc skygate.co.uk> writes:
```In article <9q2qrh\$bfo\$1 digitaldaemon.com>, "Walter"
<walter digitalmars.com> wrote:

"Ben Cohen" <bc skygate.co.uk> wrote in message
news:9q10ok\$t2h\$1 digitaldaemon.com...
In article <9q0o9a\$gch\$1 digitaldaemon.com>, "Walter"
<walter digitalmars.com> wrote:
Oh, I don't want to revisit the 3 state boolean again !! Russ Lewis
wrote in message <3BC3AF00.779903EA deming-os.org>...
<random-pondering>
Perhaps this suggests a 3-way boolean state?

It already does raise a sticky flag in the 8087 status word which you

Yes, the compiler can read that.  But the programmer isn't automatically
informed of that and will need to use all those tests you have in your
spec.

You could alternatively throw a NANException whenever an assignment is
made using an expression which produces a NAN as a result.  This is like
where you throw a DivideByZeroException when dividing by zero, except more
general.  This will be similar to Java's ArithmeticException.

E.g., log of 0, log of -1 in reals, square root of -1 in reals,
overflows...

You don't want to check for each of these cases before you do the
operation (and it might not be possible to do so).  But you can test
afterwards whether a NAN was produced.

A programmer might not test for NAN.  Since NAN is normally either fatal
to the calculation or an indication that another route must be taken, it
seems to be sensible to me that an exception is thrown.

I note that the specification also says that floats are initialised to
NAN.  This exception could (depending on how things work) also help
programmers catch the case where you use a float without first assigning a
sensible value to it.
```
Oct 11 2001
"Walter" <walter digitalmars.com> writes:
```I think throwing an exception on NAN would be more annoying to the
programmer than useful. (There are two schools of thought on this, of
course!) The flag in the status word, however, is sticky, which means that
you can test it after a long series of calculations as a global test to see
if any of it encountered a NAN. Also, printf() etc. will print out NANs as
results, so if any NANs were used they will tend to propagate through to the
output, and will be pretty obvious. -Walter

Ben Cohen wrote in message <9q3nee\$1jbm\$1 digitaldaemon.com>...
In article <9q2qrh\$bfo\$1 digitaldaemon.com>, "Walter"
<walter digitalmars.com> wrote:

"Ben Cohen" <bc skygate.co.uk> wrote in message
news:9q10ok\$t2h\$1 digitaldaemon.com...
In article <9q0o9a\$gch\$1 digitaldaemon.com>, "Walter"
<walter digitalmars.com> wrote:
Oh, I don't want to revisit the 3 state boolean again !! Russ Lewis
wrote in message <3BC3AF00.779903EA deming-os.org>...
<random-pondering>
Perhaps this suggests a 3-way boolean state?

It already does raise a sticky flag in the 8087 status word which you

Yes, the compiler can read that.  But the programmer isn't automatically
informed of that and will need to use all those tests you have in your
spec.

You could alternatively throw a NANException whenever an assignment is
made using an expression which produces a NAN as a result.  This is like
where you throw a DivideByZeroException when dividing by zero, except more
general.  This will be similar to Java's ArithmeticException.

E.g., log of 0, log of -1 in reals, square root of -1 in reals,
overflows...

You don't want to check for each of these cases before you do the
operation (and it might not be possible to do so).  But you can test
afterwards whether a NAN was produced.

A programmer might not test for NAN.  Since NAN is normally either fatal
to the calculation or an indication that another route must be taken, it
seems to be sensible to me that an exception is thrown.

I note that the specification also says that floats are initialised to
NAN.  This exception could (depending on how things work) also help
programmers catch the case where you use a float without first assigning a
sensible value to it.

```
Oct 11 2001
"Sean L. Palmer" <spalmer iname.com> writes:
``` I note that the specification also says that floats are initialised to
NAN.  This exception could (depending on how things work) also help
programmers catch the case where you use a float without first assigning a
sensible value to it.

Personally I'd prefer if floats get initialized to zero, like the ints are.
Bit representation of float zero is, according to the IEEE spec, all zero
bits.  Makes initialization code in the code generator simple (fill blocks
of basic data types with zero bits) and is more consistent.  The compiler
should already be able to tell if you're trying to use a variable that
hasn't been initialized.

The exception for nan sounds reasonable but I'd be worried about hidden
runtime costs.

Sean
```
Oct 23 2001