www.digitalmars.com         C & C++   DMDScript  

D - Floating Point RelOps

reply 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
parent reply "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
parent reply 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
parent reply "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;

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

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

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

state would be????

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

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

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
parent reply "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?


What about throwing a NANException instead?
Oct 10 2001
parent reply "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 read.
Oct 10 2001
parent reply "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 can read.

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
next sibling parent "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 can read.

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
prev sibling parent "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