comp.lang.ada
 help / color / mirror / Atom feed
* How to check a Float for NaN
@ 2008-04-30 10:27 Jerry
  2008-04-30 10:47 ` christoph.grein
                   ` (3 more replies)
  0 siblings, 4 replies; 51+ messages in thread
From: Jerry @ 2008-04-30 10:27 UTC (permalink / raw)


How would one check a Float or Long_Float if it has value NaN? The
only ways that I can come up with are to import a C function (isnan, I
think) or to write Long_Float'image(Some_Float) to a string and
examine the first three characters to see if they are "NaN" (and that
seems to be a GNAT implementation choice so might not be portable,
which is OK for my use).

Jerry




^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: How to check a Float for NaN
  2008-04-30 10:27 How to check a Float for NaN Jerry
@ 2008-04-30 10:47 ` christoph.grein
  2008-04-30 10:50   ` christoph.grein
  2008-04-30 20:36 ` Jerry
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 51+ messages in thread
From: christoph.grein @ 2008-04-30 10:47 UTC (permalink / raw)


Try Float'Valid (X), see RM 13.9.2



^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: How to check a Float for NaN
  2008-04-30 10:47 ` christoph.grein
@ 2008-04-30 10:50   ` christoph.grein
  2008-04-30 15:02     ` Adam Beneschan
  0 siblings, 1 reply; 51+ messages in thread
From: christoph.grein @ 2008-04-30 10:50 UTC (permalink / raw)


On 30 Apr., 12:47, christoph.gr...@eurocopter.com wrote:
> Try Float'Valid (X), see RM 13.9.2

Ahem, I meant X'Valid for X of type Float



^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: How to check a Float for NaN
  2008-04-30 10:50   ` christoph.grein
@ 2008-04-30 15:02     ` Adam Beneschan
  2008-04-30 20:33       ` Jerry
                         ` (2 more replies)
  0 siblings, 3 replies; 51+ messages in thread
From: Adam Beneschan @ 2008-04-30 15:02 UTC (permalink / raw)


On Apr 30, 3:50 am, christoph.gr...@eurocopter.com wrote:
> On 30 Apr., 12:47, christoph.gr...@eurocopter.com wrote:
>
> > Try Float'Valid (X), see RM 13.9.2
>
> Ahem, I meant X'Valid for X of type Float

I'm not sure if this will produce the desired results, since it should
return False for +/- infinity also.  That may be OK with the original
poster, or not.

The problem here is that if you're dealing with NaN's on purpose,
you're not really dealing with Ada, as far as I can tell, unless your
purpose is to test for an uninitialized variable (in which case
X'Valid makes sense).  Otherwise, though, NaN's and infinities are not
possible values of floating-point types, and therefore they can't be
returned by operations that return floating-point values, even if
Float'Machine_Overflows is False.  (There are certain passages in the
RM that say a result is implementation-defined if the
Machine_Overflows attribute is False; however, I do not think
assigning a variable to an invalid value, as a NaN would be, is an
allowed "implementation-defined" result.  13.9.2(4-11) lists the ways
that invalid data could be created, and the "result of a floating-
point operation that cannot return a valid result" is not one of those
listed.  Yes, I know that this is a NOTE and is not normative.)

Of course, if you compile with checking turned off or your code does
something to turn off the floating-point overflow-checking bit in the
processor (if there is one), you're outside the bounds of Ada, so you
can't really come up with an Ada solution to the question, and
whatever you do won't be portable.  In that case, "whatever works" is
fine.  If I had to do this, I'd just do an Unchecked_Conversion to
some data structure with a rep clause that represents an  IEEE-754
float, or to a modular integer type or array of modular integer types,
and then just test the bits myself.  Testing the 'Image for "NaN" will
probably work, but if efficiency is a concern I wouldn't do this
because if the float is a valid one, it's a *lot* of work to convert
the float to a decimal representation, and that's especially painful
here because you're just going to throw all that work out.

P.S. Has the ARG or anyone discussed the possibility of building
support for infinities and/or NaN's into the language---i.e. defining
a floating-point type that includes those "values"?  G.1.1(56) makes
me think that maybe there were some thoughts that this might be done
sometime in the future, if there's a demand for it, but I could be
reading something into this paragraph that isn't there.

                                   -- Adam




^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: How to check a Float for NaN
  2008-04-30 15:02     ` Adam Beneschan
@ 2008-04-30 20:33       ` Jerry
  2008-04-30 23:23         ` Adam Beneschan
  2008-04-30 23:29       ` Randy Brukardt
  2008-05-01  8:04       ` Stuart
  2 siblings, 1 reply; 51+ messages in thread
From: Jerry @ 2008-04-30 20:33 UTC (permalink / raw)


On Apr 30, 8:02 am, Adam Beneschan <a...@irvine.com> wrote:
> On Apr 30, 3:50 am, christoph.gr...@eurocopter.com wrote:
>
> > On 30 Apr., 12:47, christoph.gr...@eurocopter.com wrote:
>
> > > Try Float'Valid (X), see RM 13.9.2
>
> > Ahem, I meant X'Valid for X of type Float
>
> I'm not sure if this will produce the desired results, since it should
> return False for +/- infinity also.  That may be OK with the original
> poster, or not.
>
> The problem here is that if you're dealing with NaN's on purpose,
> you're not really dealing with Ada, as far as I can tell, unless your
> purpose is to test for an uninitialized variable (in which case
> X'Valid makes sense).  Otherwise, though, NaN's and infinities are not
> possible values of floating-point types, and therefore they can't be
> returned by operations that return floating-point values, even if
> Float'Machine_Overflows is False.  (There are certain passages in the
> RM that say a result is implementation-defined if the
> Machine_Overflows attribute is False; however, I do not think
> assigning a variable to an invalid value, as a NaN would be, is an
> allowed "implementation-defined" result.  13.9.2(4-11) lists the ways
> that invalid data could be created, and the "result of a floating-
> point operation that cannot return a valid result" is not one of those
> listed.  Yes, I know that this is a NOTE and is not normative.)
>
> Of course, if you compile with checking turned off or your code does
> something to turn off the floating-point overflow-checking bit in the
> processor (if there is one), you're outside the bounds of Ada, so you
> can't really come up with an Ada solution to the question, and
> whatever you do won't be portable.  In that case, "whatever works" is
> fine.  If I had to do this, I'd just do an Unchecked_Conversion to
> some data structure with a rep clause that represents an  IEEE-754
> float, or to a modular integer type or array of modular integer types,
> and then just test the bits myself.  Testing the 'Image for "NaN" will
> probably work, but if efficiency is a concern I wouldn't do this
> because if the float is a valid one, it's a *lot* of work to convert
> the float to a decimal representation, and that's especially painful
> here because you're just going to throw all that work out.
>
> P.S. Has the ARG or anyone discussed the possibility of building
> support for infinities and/or NaN's into the language---i.e. defining
> a floating-point type that includes those "values"?  G.1.1(56) makes
> me think that maybe there were some thoughts that this might be done
> sometime in the future, if there's a demand for it, but I could be
> reading something into this paragraph that isn't there.
>
>                                    -- Adam

Thanks for the insight. From my point of view, not having access to
the all the IEEE-754 features is a nuisance. I'm not sure what I'm
going to do--probably try in import the C function isnan. My need
isn't terribly important--just converting an example for PLplot that
is written in C. Frankly, I'm a little surprised that this isn't
handled by Ada--but I'm sure there's an excellent reason ;).

FWIW, I just now found this passage from the Annotated ARM at
http://www.adaic.org/standards/05aarm/html/AA-A-5-1.html, in A.5.1,
34.b (IEC 559 = IEEE 754):

"Discussion: It is anticipated that an Ada binding to IEC 559:1989
will be developed in the future. As part of such a binding, the
Machine_Overflows attribute of a conformant floating point type will
be specified to yield False, which will permit both the predefined
arithmetic operations and implementations of the elementary functions
to deliver signed infinities (and set the overflow flag defined by the
binding) instead of raising Constraint_Error in overflow situations,
when traps are disabled. Similarly, it is appropriate for the
elementary functions to deliver signed infinities (and set the zero-
divide flag defined by the binding) instead of raising
Constraint_Error at poles, when traps are disabled. Finally, such a
binding should also specify the behavior of the elementary functions,
when sensible, given parameters with infinite values."

Jerry





^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: How to check a Float for NaN
  2008-04-30 10:27 How to check a Float for NaN Jerry
  2008-04-30 10:47 ` christoph.grein
@ 2008-04-30 20:36 ` Jerry
  2008-04-30 21:53   ` Adam Beneschan
  2014-05-22  7:27   ` jan.de.kruyf
  2008-05-05 18:23 ` Martin Krischik
  2008-05-09 19:49 ` anon
  3 siblings, 2 replies; 51+ messages in thread
From: Jerry @ 2008-04-30 20:36 UTC (permalink / raw)


On Apr 30, 3:27 am, Jerry <lancebo...@qwest.net> wrote:
> How would one check a Float or Long_Float if it has value NaN? The
> only ways that I can come up with are to import a C function (isnan, I
> think) or to write Long_Float'image(Some_Float) to a string and
> examine the first three characters to see if they are "NaN" (and that
> seems to be a GNAT implementation choice so might not be portable,
> which is OK for my use).
>
> Jerry

Check this out:

function Is_NaN(x : Long_Float) return Boolean is
begin
    return x /= x;
end Is_NaN;

A couple of minutes on Wikipedia saves the day. From
http://en.wikipedia.org/wiki/NaN#NaN_encodings:

"A NaN does not compare equal to any floating-point number or NaN,
even if the latter has an identical representation. One can therefore
test whether a variable has a NaN value by comparing it to itself."

Jerry



^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: How to check a Float for NaN
  2008-04-30 20:36 ` Jerry
@ 2008-04-30 21:53   ` Adam Beneschan
  2008-05-01  1:05     ` Jerry
  2014-05-22  7:27   ` jan.de.kruyf
  1 sibling, 1 reply; 51+ messages in thread
From: Adam Beneschan @ 2008-04-30 21:53 UTC (permalink / raw)


On Apr 30, 1:36 pm, Jerry <lancebo...@qwest.net> wrote:

> Check this out:
>
> function Is_NaN(x : Long_Float) return Boolean is
> begin
>     return x /= x;
> end Is_NaN;

Maybe that will work, but I wouldn't count on it.  First of all, you
don't know that the compiler will actually do anything.  It may get
clever and decide that this is trivially False, and thus generate code
that doesn't even look at x.  Second, if it generates a "floating-
point comparison" instruction, you may not get the behavior you think
you're getting.  My Pentium manual, for instance, says of the FCOM*
(Compare Real) instructions: "If either operand is a NaN or is in an
undefined format, ... the invalid-operation exception is raised, and
the condition bits are set to 'unordered'".  Which means that (on that
processor) the comparison attempt will probably fault, and if it
doesn't because the fault is masked, the condition-code bits will be
set to an "unordered" relation that your compiler may not be
expecting, which means that it may not be translated to "inequality"
the way you think it will.


> A couple of minutes on Wikipedia saves the day. Fromhttp://en.wikipedia.org/wiki/NaN#NaN_encodings:
>
> "A NaN does not compare equal to any floating-point number or NaN,
> even if the latter has an identical representation. One can therefore
> test whether a variable has a NaN value by comparing it to itself."

But if you read further, you'll find that signaling NaNs "should raise
an invalid exception".  (Why the Pentium FCOM instructions appear to
raise exceptions for quiet NaN's as well as signed NaN's, I don't
know.)

Anyway, Wikipedia describes the IEC 559/IEEE 754 standard, but as
we've already discussed, (1) Ada doesn't fully support this standard
and (2) NaN's aren't valid values in Ada, so you can't reliably use
the IEC/IEEE standard to predict what will happen if you do this in
Ada.  You're welcome to try it, of course, but don't be surprised or
disappointed if it doesn't work.

                                 -- Adam




^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: How to check a Float for NaN
  2008-04-30 20:33       ` Jerry
@ 2008-04-30 23:23         ` Adam Beneschan
  2008-05-01  1:00           ` Adam Beneschan
  0 siblings, 1 reply; 51+ messages in thread
From: Adam Beneschan @ 2008-04-30 23:23 UTC (permalink / raw)


On Apr 30, 1:33 pm, Jerry <lancebo...@qwest.net> wrote:

> Thanks for the insight. From my point of view, not having access to
> the all the IEEE-754 features is a nuisance. I'm not sure what I'm
> going to do--probably try in import the C function isnan.

Be careful with that, too.  On my (Pentium Linux) system, the man page
for "isnan" says it takes a "double", which I think means a 64-bit
float.  You'll probably be OK if you use a 64-bit float type (probably
Long_Float).  But if you want to test a 32-bit float type, I don't see
a C function that works on 32-bit floats, and doing an Ada type
conversion is very likely to fail---probably cause a processor fault
when the compiler generates a floating-point conversion instruction
and the processor then faults because you gave it a NaN as an
instruction operand.

                               -- Adam



^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: How to check a Float for NaN
  2008-04-30 15:02     ` Adam Beneschan
  2008-04-30 20:33       ` Jerry
@ 2008-04-30 23:29       ` Randy Brukardt
  2008-05-01  8:04       ` Stuart
  2 siblings, 0 replies; 51+ messages in thread
From: Randy Brukardt @ 2008-04-30 23:29 UTC (permalink / raw)


"Adam Beneschan" <adam@irvine.com> wrote in message
news:93b0d930-102a-4ac4-8b85-48e87d9d3df1@j33g2000pri.googlegroups.com...
...
> P.S. Has the ARG or anyone discussed the possibility of building
> support for infinities and/or NaN's into the language---i.e. defining
> a floating-point type that includes those "values"?  G.1.1(56) makes
> me think that maybe there were some thoughts that this might be done
> sometime in the future, if there's a demand for it, but I could be
> reading something into this paragraph that isn't there.

The "Rationale for Ada 2005" notes that AI95-00315 proposed such support:
see http://www.adaic.com/standards/05rat/html/Rat-9-3-3.html.

To expand a bit on the reasons for not including this: The proposal would
have required vastly different (and much worse in general) code generation
and optimization: much of what you can prove about values and expressions
goes out the window when you include NaNs and infinitities in the equation.
The proposal suggested a different mode for this, but some implementers did
not want to have to really support separate modes (they treat the "relaxed"
and "strict" modes the same). Moreover, the ARG didn't have any experts that
could really tell us if the proposal was useful or overkill, and vendors
didn't seem to have paying customers with specific concerns. As such, there
was no consensus on how to proceed, and it was tabled to put our energies
toward areas that we understood and had consensus for.

I believe the ARG will revisit this area if we get the right expertise (and
vendors have paying customers who care: I know RR does not have such
customers today).

                         Randy.







^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: How to check a Float for NaN
  2008-04-30 23:23         ` Adam Beneschan
@ 2008-05-01  1:00           ` Adam Beneschan
  2008-05-01 19:52             ` Keith Thompson
  0 siblings, 1 reply; 51+ messages in thread
From: Adam Beneschan @ 2008-05-01  1:00 UTC (permalink / raw)


On Apr 30, 4:23 pm, I wrote:
> On Apr 30, 1:33 pm, Jerry <lancebo...@qwest.net> wrote:
>
> > Thanks for the insight. From my point of view, not having access to
> > the all the IEEE-754 features is a nuisance. I'm not sure what I'm
> > going to do--probably try in import the C function isnan.
>
> Be careful with that, too.  On my (Pentium Linux) system, the man page
> for "isnan" says it takes a "double", which I think means a 64-bit
> float.

Ha, ha, ha, the man page lied.  Apparently (on my system) isnan is a C
macro (in <math.h>), which will call one of three routines depending
on the size of the float.  But since isnan is a macro, doing an Import
pragma on it is likely going to fail since "isnan" is not the name of
an actual routine in the library.  That's on my OS, though; who knows
how it works on yours.

Anyway, good luck and have fun getting this to work.

                               -- Adam



^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: How to check a Float for NaN
  2008-04-30 21:53   ` Adam Beneschan
@ 2008-05-01  1:05     ` Jerry
  0 siblings, 0 replies; 51+ messages in thread
From: Jerry @ 2008-05-01  1:05 UTC (permalink / raw)


On Apr 30, 2:53 pm, Adam Beneschan <a...@irvine.com> wrote:
> On Apr 30, 1:36 pm, Jerry <lancebo...@qwest.net> wrote:
>
> > Check this out:
>
> > function Is_NaN(x : Long_Float) return Boolean is
> > begin
> >     return x /= x;
> > end Is_NaN;
>
> Maybe that will work, but I wouldn't count on it.  First of all, you
> don't know that the compiler will actually do anything.  It may get
> clever and decide that this is trivially False, and thus generate code
> that doesn't even look at x.  Second, if it generates a "floating-
> point comparison" instruction, you may not get the behavior you think
> you're getting.  My Pentium manual, for instance, says of the FCOM*
> (Compare Real) instructions: "If either operand is a NaN or is in an
> undefined format, ... the invalid-operation exception is raised, and
> the condition bits are set to 'unordered'".  Which means that (on that
> processor) the comparison attempt will probably fault, and if it
> doesn't because the fault is masked, the condition-code bits will be
> set to an "unordered" relation that your compiler may not be
> expecting, which means that it may not be translated to "inequality"
> the way you think it will.
>
> > A couple of minutes on Wikipedia saves the day. Fromhttp://en.wikipedia.org/wiki/NaN#NaN_encodings:
>
> > "A NaN does not compare equal to any floating-point number or NaN,
> > even if the latter has an identical representation. One can therefore
> > test whether a variable has a NaN value by comparing it to itself."
>
> But if you read further, you'll find that signaling NaNs "should raise
> an invalid exception".  (Why the Pentium FCOM instructions appear to
> raise exceptions for quiet NaN's as well as signed NaN's, I don't
> know.)
>
> Anyway, Wikipedia describes the IEC 559/IEEE 754 standard, but as
> we've already discussed, (1) Ada doesn't fully support this standard
> and (2) NaN's aren't valid values in Ada, so you can't reliably use
> the IEC/IEEE standard to predict what will happen if you do this in
> Ada.  You're welcome to try it, of course, but don't be surprised or
> disappointed if it doesn't work.
>
>                                  -- Adam

Adam,
Your points are well made. For "normal" use my little hack should be
considered suspect. For my trivial use of getting this pesky binding
example code out of my hair, I think it should be OK.

Just for completeness, I suppose, I'll add (as I alluded to in my
original post), that this:

    dum1 := 0.0;
    dum2 := 0.0;
    Put_Line(Long_Float'image(dum1 / dum2));

outputs this:

NaN*****************

Certainly not 754 compliance, but perhaps a bit of "awareness."
Jerry



^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: How to check a Float for NaN
  2008-04-30 15:02     ` Adam Beneschan
  2008-04-30 20:33       ` Jerry
  2008-04-30 23:29       ` Randy Brukardt
@ 2008-05-01  8:04       ` Stuart
  2008-05-01 14:38         ` Adam Beneschan
  2008-05-02  0:04         ` Jerry
  2 siblings, 2 replies; 51+ messages in thread
From: Stuart @ 2008-05-01  8:04 UTC (permalink / raw)


"Adam Beneschan" <adam@irvine.com> wrote in message 
news:93b0d930-102a-4ac4-8b85-48e87d9d3df1@j33g2000pri.googlegroups.com...
> On Apr 30, 3:50 am, christoph.gr...@eurocopter.com wrote:
>> On 30 Apr., 12:47, christoph.gr...@eurocopter.com wrote:
>>
>> > Try Float'Valid (X), see RM 13.9.2
>>
>> Ahem, I meant X'Valid for X of type Float
<snip>

> The problem here is that if you're dealing with NaN's on purpose,
> you're not really dealing with Ada, as far as I can tell, unless your
> purpose is to test for an uninitialized variable (in which case
> X'Valid makes sense).  Otherwise, though, NaN's and infinities are not
> possible values of floating-point types, and therefore they can't be
> returned by operations that return floating-point values, even if
> Float'Machine_Overflows is False.  (There are certain passages in the
> RM that say a result is implementation-defined if the
> Machine_Overflows attribute is False; however, I do not think
> assigning a variable to an invalid value, as a NaN would be, is an
> allowed "implementation-defined" result.  13.9.2(4-11) lists the ways
> that invalid data could be created, and the "result of a floating-
> point operation that cannot return a valid result" is not one of those
> listed.  Yes, I know that this is a NOTE and is not normative.)

Would not 13.9.2(10) cover this:
   "disrupting an assignment due to the failure of a language-defined check 
(see 11.6)"

Thus if a floating point operation creates a NaN, which would indicate an 
ill-conditioned computation that should violate some language-defined check, 
the object (X) that was to receive the result would be considered invalid.

As noted elsewhere, 'valid encompasses more than NaNs - which may or may not 
suit the OPs purpose.

Regards
-- 
Stuart 





^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: How to check a Float for NaN
  2008-05-01  8:04       ` Stuart
@ 2008-05-01 14:38         ` Adam Beneschan
  2008-05-01 17:14           ` Stuart
  2008-05-02  0:04         ` Jerry
  1 sibling, 1 reply; 51+ messages in thread
From: Adam Beneschan @ 2008-05-01 14:38 UTC (permalink / raw)


On May 1, 1:04 am, "Stuart" <stu...@0.0> wrote:
> "Adam Beneschan" <a...@irvine.com> wrote in message

> > 13.9.2(4-11) lists the ways
> > that invalid data could be created, and the "result of a floating-
> > point operation that cannot return a valid result" is not one of those
> > listed.  Yes, I know that this is a NOTE and is not normative.)
>
> Would not 13.9.2(10) cover this:
>    "disrupting an assignment due to the failure of a language-defined check
> (see 11.6)"

Did you read 11.6?

I think all this says is that if an assignment statement raises an
exception (due to a language-defined check), then in the exception
handler and further on in the code, you can't count on the value of
the target object being normal.  You can't count on it being abnormal,
either.  But if no exception is raised, then this doesn't apply.

                               -- Adam



^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: How to check a Float for NaN
  2008-05-01 14:38         ` Adam Beneschan
@ 2008-05-01 17:14           ` Stuart
  2008-05-01 19:22             ` Randy Brukardt
  0 siblings, 1 reply; 51+ messages in thread
From: Stuart @ 2008-05-01 17:14 UTC (permalink / raw)


"Adam Beneschan" <adam@irvine.com> wrote in message 
news:fe6a8cc1-eac7-4b25-bd21-39f9c2015c4a@k1g2000prb.googlegroups.com...
> On May 1, 1:04 am, "Stuart" <stu...@0.0> wrote:
>> "Adam Beneschan" <a...@irvine.com> wrote in message
>
>> > 13.9.2(4-11) lists the ways
>> > that invalid data could be created, and the "result of a floating-
>> > point operation that cannot return a valid result" is not one of those
>> > listed.  Yes, I know that this is a NOTE and is not normative.)
>>
>> Would not 13.9.2(10) cover this:
>>    "disrupting an assignment due to the failure of a language-defined 
>> check
>> (see 11.6)"
>
> Did you read 11.6?

I tried, but legalese is not my first language and I find some of the 
'language lawyerly' stuff rather impenetrable at times. ;-)

> I think all this says is that if an assignment statement raises an
> exception (due to a language-defined check), then in the exception
> handler and further on in the code, you can't count on the value of
> the target object being normal.  You can't count on it being abnormal,
> either.  But if no exception is raised, then this doesn't apply.

I agree with what you are saying here; which I read as 'you can't count on 
the target object being obviously invalid (e.g. a NaN), but it _could_ be'. 
As such 13.9.2(10) appears to support a case by which a NaN value could 
arise in an object during computation.

In a nominal Ada program it would be sensible to deal with the situation in 
the exception handler, rather than let it slide and try and resolve it later 
using 'valid.  But then, I think, we are picking-over the innards of some 
murky corner case of the language - so good-sense need not apply ;-)

I would hazard a guess that we have strayed well away from the OP's original 
area of interest (he was probably validating inputs), and as you noted 
earlier.

Regards
-- 
Stuart 





^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: How to check a Float for NaN
  2008-05-01 17:14           ` Stuart
@ 2008-05-01 19:22             ` Randy Brukardt
  0 siblings, 0 replies; 51+ messages in thread
From: Randy Brukardt @ 2008-05-01 19:22 UTC (permalink / raw)


"Stuart" <stuart@0.0> wrote in message
news:4819f65b$1_1@glkas0286.greenlnk.net...
> "Adam Beneschan" <adam@irvine.com> wrote in message
> news:fe6a8cc1-eac7-4b25-bd21-39f9c2015c4a@k1g2000prb.googlegroups.com...
...
> >> Would not 13.9.2(10) cover this:
> >>    "disrupting an assignment due to the failure of a language-defined
> >> check
> >> (see 11.6)"
> >
> > Did you read 11.6?
>
> I tried, but legalese is not my first language and I find some of the
> 'language lawyerly' stuff rather impenetrable at times. ;-)

If either of you can clearly understand and explain 11.6, then you need to
join the ARG immediately and explain it to us. ;-)

Seriously, 11.6 is a very murky part of the Standard, while everyone
understands what is generally intended, its not clear that the wording
actually has the right effect in many detailed cases. Nor is it clear
exactly what boundaries are correct. It was the best that the Ada 95 team
could do, and no one much wants to open the can of worms that it represents.

We had a series of lengthy and rather heated discussions about the data
validity model in Ada during the Amendment process. We were trying to fix
the Ada 95 problem that if an Unchecked_Conversion produces an invalid
result, using 'Valid to check that result made your program erroneous (thus,
'Valid could always return True in that case, and in fact at least one
compiler did that). We hacked around with the rules to eliminate that
particular problem (at the cost of making them much more complex).

But we weren't able to completely eliminate the problem (exceptions still
can be raised in this case): the problem being one camp that thinks that
there should be no checks on Unchecked_Conversion ever and the other camp
that will not allow valid objects to become invalid in any circumstances
(the alternative being erroneous execution, which is uncalled for for
something whose primary purpose is to eliminate checks). We ended up
compromising in the middle (I would have preferred to get rid of the
erroneousness completely, but at least the current rules don't require an
implementer to generate erroneous programs - you can make extra checks to
prevent it).

                                  Randy.





^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: How to check a Float for NaN
  2008-05-01  1:00           ` Adam Beneschan
@ 2008-05-01 19:52             ` Keith Thompson
  2008-05-01 23:57               ` Jerry
  0 siblings, 1 reply; 51+ messages in thread
From: Keith Thompson @ 2008-05-01 19:52 UTC (permalink / raw)


Adam Beneschan <adam@irvine.com> writes:
> On Apr 30, 4:23 pm, I wrote:
>> On Apr 30, 1:33 pm, Jerry <lancebo...@qwest.net> wrote:
>> > Thanks for the insight. From my point of view, not having access to
>> > the all the IEEE-754 features is a nuisance. I'm not sure what I'm
>> > going to do--probably try in import the C function isnan.
>>
>> Be careful with that, too.  On my (Pentium Linux) system, the man page
>> for "isnan" says it takes a "double", which I think means a 64-bit
>> float.
>
> Ha, ha, ha, the man page lied.  Apparently (on my system) isnan is a C
> macro (in <math.h>), which will call one of three routines depending
> on the size of the float.  But since isnan is a macro, doing an Import
> pragma on it is likely going to fail since "isnan" is not the name of
> an actual routine in the library.  That's on my OS, though; who knows
> how it works on yours.
>
> Anyway, good luck and have fun getting this to work.

The C99 C standard (which is not widely implemented, at least not
completely) specifies that isnan() is a macro that can take an
argument of any floating-point type (float, double, long double).  It
might typically be implemented by invoking one of three functions
depending on the size of the argument, but the standard doesn't
specify any particular method; it could be pure magic.  The earlier
C90 standard doesn't provide any such floating-point classification
macros or functions.  Some C90 implementations might provide a
function, rather than macro, called "isnan"; perhaps that's what your
system documents.

You can't interface to a C macro from Ada (as far as I know), but you
can easily write a wrapper function.  Assuming your C implementation
provides the isnan() macro as specified by C99, you can do this:

    #include <math.h>

    int float_isnan       (float x)       { return isnan(x); }
    int double_isnan      (double x)      { return isnan(x); }
    int long_double_isnan (long double x) { return isnan(x); }

and then provide Ada interfaces to those C functions.

It's a bit of a roundabout way to do it (providing three distinct
function wrappers for a single macro that's probably a wrapper for
three distinct underlying functions), but it should work.

-- 
Keith Thompson (The_Other_Keith) <kst-u@mib.org>
Nokia
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"



^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: How to check a Float for NaN
  2008-05-01 19:52             ` Keith Thompson
@ 2008-05-01 23:57               ` Jerry
  0 siblings, 0 replies; 51+ messages in thread
From: Jerry @ 2008-05-01 23:57 UTC (permalink / raw)


On May 1, 12:52 pm, Keith Thompson <ks...@mib.org> wrote:
> Adam Beneschan <a...@irvine.com> writes:
> > On Apr 30, 4:23 pm, I wrote:
> >> On Apr 30, 1:33 pm, Jerry <lancebo...@qwest.net> wrote:
> >> > Thanks for the insight. From my point of view, not having access to
> >> > the all the IEEE-754 features is a nuisance. I'm not sure what I'm
> >> > going to do--probably try in import the C function isnan.
>
> >> Be careful with that, too.  On my (Pentium Linux) system, the man page
> >> for "isnan" says it takes a "double", which I think means a 64-bit
> >> float.
>
> > Ha, ha, ha, the man page lied.  Apparently (on my system) isnan is a C
> > macro (in <math.h>), which will call one of three routines depending
> > on the size of the float.  But since isnan is a macro, doing an Import
> > pragma on it is likely going to fail since "isnan" is not the name of
> > an actual routine in the library.  That's on my OS, though; who knows
> > how it works on yours.
>
> > Anyway, good luck and have fun getting this to work.
>
> The C99 C standard (which is not widely implemented, at least not
> completely) specifies that isnan() is a macro that can take an
> argument of any floating-point type (float, double, long double).  It
> might typically be implemented by invoking one of three functions
> depending on the size of the argument, but the standard doesn't
> specify any particular method; it could be pure magic.  The earlier
> C90 standard doesn't provide any such floating-point classification
> macros or functions.  Some C90 implementations might provide a
> function, rather than macro, called "isnan"; perhaps that's what your
> system documents.
>
> You can't interface to a C macro from Ada (as far as I know), but you
> can easily write a wrapper function.  Assuming your C implementation
> provides the isnan() macro as specified by C99, you can do this:
>
>     #include <math.h>
>
>     int float_isnan       (float x)       { return isnan(x); }
>     int double_isnan      (double x)      { return isnan(x); }
>     int long_double_isnan (long double x) { return isnan(x); }
>
> and then provide Ada interfaces to those C functions.
>
> It's a bit of a roundabout way to do it (providing three distinct
> function wrappers for a single macro that's probably a wrapper for
> three distinct underlying functions), but it should work.
>
> --
> Keith Thompson (The_Other_Keith) <ks...@mib.org>
> Nokia
> "We must do something.  This is something.  Therefore, we must do this."
>     -- Antony Jay and Jonathan Lynn, "Yes Minister"

That looks doable.

As an aside, I remember the early Pascal compilers on Macintosh
(Apple's own and the much-missed THINK Pascal nee MacPascal) dealt
with all of the 754 spec (as far as I know, which isn't very far) and
was very well documented in a book called Apple Numerics Manual with
unspecified authorship but with a forward by Prof. Kahan of UC
Berkeley. MacPascal did 96-bit floating point when it ran without
hardware acceleration and fell back to 80 bits with a FPU.

Jerry



^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: How to check a Float for NaN
  2008-05-01  8:04       ` Stuart
  2008-05-01 14:38         ` Adam Beneschan
@ 2008-05-02  0:04         ` Jerry
  1 sibling, 0 replies; 51+ messages in thread
From: Jerry @ 2008-05-02  0:04 UTC (permalink / raw)


On May 1, 1:04 am, "Stuart" <stu...@0.0> wrote:
> "Adam Beneschan" <a...@irvine.com> wrote in message
>
> news:93b0d930-102a-4ac4-8b85-48e87d9d3df1@j33g2000pri.googlegroups.com...> On Apr 30, 3:50 am, christoph.gr...@eurocopter.com wrote:
> >> On 30 Apr., 12:47, christoph.gr...@eurocopter.com wrote:
>
> >> > Try Float'Valid (X), see RM 13.9.2
>
> >> Ahem, I meant X'Valid for X of type Float
>
> <snip>
>
> > The problem here is that if you're dealing with NaN's on purpose,
> > you're not really dealing with Ada, as far as I can tell, unless your
> > purpose is to test for an uninitialized variable (in which case
> > X'Valid makes sense).  Otherwise, though, NaN's and infinities are not
> > possible values of floating-point types, and therefore they can't be
> > returned by operations that return floating-point values, even if
> > Float'Machine_Overflows is False.  (There are certain passages in the
> > RM that say a result is implementation-defined if the
> > Machine_Overflows attribute is False; however, I do not think
> > assigning a variable to an invalid value, as a NaN would be, is an
> > allowed "implementation-defined" result.  13.9.2(4-11) lists the ways
> > that invalid data could be created, and the "result of a floating-
> > point operation that cannot return a valid result" is not one of those
> > listed.  Yes, I know that this is a NOTE and is not normative.)
>
> Would not 13.9.2(10) cover this:
>    "disrupting an assignment due to the failure of a language-defined check
> (see 11.6)"
>
> Thus if a floating point operation creates a NaN, which would indicate an
> ill-conditioned computation that should violate some language-defined check,
> the object (X) that was to receive the result would be considered invalid.
>
> As noted elsewhere, 'valid encompasses more than NaNs - which may or may not
> suit the OPs purpose.

Not sure. Apparently, the plotting example I'm translating from C
needs to check for NaN when the underlying surface plot machinery is
working. It seems odd that this heavy a responsibility should appear
to the user in an example, but that's out of my control. I suppose
'valid would work since I doubt that other pathologies would arise.

Jerry
>
> Regards
> --
> Stuart




^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: How to check a Float for NaN
  2008-04-30 10:27 How to check a Float for NaN Jerry
  2008-04-30 10:47 ` christoph.grein
  2008-04-30 20:36 ` Jerry
@ 2008-05-05 18:23 ` Martin Krischik
  2008-05-05 20:49   ` Adam Beneschan
  2008-05-10 17:00   ` anon
  2008-05-09 19:49 ` anon
  3 siblings, 2 replies; 51+ messages in thread
From: Martin Krischik @ 2008-05-05 18:23 UTC (permalink / raw)


Jerry wrote:

> How would one check a Float or Long_Float if it has value NaN? The
> only ways that I can come up with are to import a C function (isnan, I
> think) or to write Long_Float'image(Some_Float) to a string and
> examine the first three characters to see if they are "NaN" (and that
> seems to be a GNAT implementation choice so might not be portable,
> which is OK for my use).

How about an Unchecked Conversion to an Unsigned_64 and comparing
>2#0111_1111_1111_0000_0000_0000_0000_0000#

Note that it's '>' as 2#0111_1111_1111_0000_0000_0000_0000_0000# is positive
infinity.

Martin
-- 
mailto://krischik@users.sourceforge.net
Ada programming at: http://ada.krischik.com



^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: How to check a Float for NaN
  2008-05-05 18:23 ` Martin Krischik
@ 2008-05-05 20:49   ` Adam Beneschan
  2008-05-06 18:09     ` Jerry
  2008-05-10 17:00   ` anon
  1 sibling, 1 reply; 51+ messages in thread
From: Adam Beneschan @ 2008-05-05 20:49 UTC (permalink / raw)


On May 5, 11:23 am, Martin Krischik <krisc...@users.sourceforge.net>
wrote:
> Jerry wrote:
> > How would one check a Float or Long_Float if it has value NaN? The
> > only ways that I can come up with are to import a C function (isnan, I
> > think) or to write Long_Float'image(Some_Float) to a string and
> > examine the first three characters to see if they are "NaN" (and that
> > seems to be a GNAT implementation choice so might not be portable,
> > which is OK for my use).
>
> How about an Unchecked Conversion to an Unsigned_64 and comparing
>
> >2#0111_1111_1111_0000_0000_0000_0000_0000#
>
> Note that it's '>' as 2#0111_1111_1111_0000_0000_0000_0000_0000# is positive
> infinity.

Any negative float (including negative infinity) would be > than the
binary number you give, since the leftmost bit (sign bit) would be 1.
I think you need to clear the sign bit first, then your comparison
will work:

  Is_NaN := (To_Unsigned_64(X) and not
              2#1000_0000_0000_0000_0000_0000_0000_0000#)
             > 2#0111_1111_1111_0000_0000_0000_0000_0000#;

But I haven't tried it.

                                  -- Adam





^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: How to check a Float for NaN
  2008-05-05 20:49   ` Adam Beneschan
@ 2008-05-06 18:09     ` Jerry
  2008-05-06 18:45       ` Wiljan Derks
  0 siblings, 1 reply; 51+ messages in thread
From: Jerry @ 2008-05-06 18:09 UTC (permalink / raw)


On May 5, 1:49 pm, Adam Beneschan <a...@irvine.com> wrote:
> On May 5, 11:23 am, Martin Krischik <krisc...@users.sourceforge.net>
> wrote:
>
> > Jerry wrote:
> > > How would one check a Float or Long_Float if it has value NaN? The
> > > only ways that I can come up with are to import a C function (isnan, I
> > > think) or to write Long_Float'image(Some_Float) to a string and
> > > examine the first three characters to see if they are "NaN" (and that
> > > seems to be a GNAT implementation choice so might not be portable,
> > > which is OK for my use).
>
> > How about an Unchecked Conversion to an Unsigned_64 and comparing
>
> > >2#0111_1111_1111_0000_0000_0000_0000_0000#
>
> > Note that it's '>' as 2#0111_1111_1111_0000_0000_0000_0000_0000# is positive
> > infinity.
>
> Any negative float (including negative infinity) would be > than the
> binary number you give, since the leftmost bit (sign bit) would be 1.
> I think you need to clear the sign bit first, then your comparison
> will work:
>
>   Is_NaN := (To_Unsigned_64(X) and not
>               2#1000_0000_0000_0000_0000_0000_0000_0000#)
>              > 2#0111_1111_1111_0000_0000_0000_0000_0000#;
>
> But I haven't tried it.
>
>                                   -- Adam

I thought about doing something like this once I saw the bit patterns
on the Wikipedia page. However, I would guess that the bit pattern for
quiet and signaling NaNs is different, so the test would be somewhat
more complicated if one wanted to detect both types.

Jerry



^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: How to check a Float for NaN
  2008-05-06 18:09     ` Jerry
@ 2008-05-06 18:45       ` Wiljan Derks
  2008-05-06 22:18         ` Adam Beneschan
  0 siblings, 1 reply; 51+ messages in thread
From: Wiljan Derks @ 2008-05-06 18:45 UTC (permalink / raw)


The following code works fine for us:

   type Ieee_Short_Real is
      record
         Mantisse_Sign : Integer range 0 .. 1;
         Exponent      : Integer range 0 .. 2 **  8 - 1;
         Mantisse      : Integer range 0 .. 2 ** 23 - 1;
      end record;

   for Ieee_Short_Real use
      record
         Mantisse_Sign at 0 range 31 .. 31;
         Exponent      at 0 range 23 .. 30;
         Mantisse      at 0 range  0 .. 22;
      end record;

   function Valid_Real (Number : Float) return Boolean is
      function To_Ieee_Short_Real is
         new Ada.Unchecked_Conversion (Float, Ieee_Short_Real);
   begin
      return To_Ieee_Short_Real (Number).Exponent /= 255;
   end Valid_Real;

Wiljan





^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: How to check a Float for NaN
  2008-05-06 18:45       ` Wiljan Derks
@ 2008-05-06 22:18         ` Adam Beneschan
  2008-05-07 22:56           ` Randy Brukardt
  2008-05-07 22:56           ` Randy Brukardt
  0 siblings, 2 replies; 51+ messages in thread
From: Adam Beneschan @ 2008-05-06 22:18 UTC (permalink / raw)


On May 6, 11:45 am, "Wiljan Derks" <Wiljan.De...@gmail.com> wrote:
> The following code works fine for us:
>
>    type Ieee_Short_Real is
>       record
>          Mantisse_Sign : Integer range 0 .. 1;
>          Exponent      : Integer range 0 .. 2 **  8 - 1;
>          Mantisse      : Integer range 0 .. 2 ** 23 - 1;
>       end record;
>
>    for Ieee_Short_Real use
>       record
>          Mantisse_Sign at 0 range 31 .. 31;
>          Exponent      at 0 range 23 .. 30;
>          Mantisse      at 0 range  0 .. 22;
>       end record;
>
>    function Valid_Real (Number : Float) return Boolean is
>       function To_Ieee_Short_Real is
>          new Ada.Unchecked_Conversion (Float, Ieee_Short_Real);
>    begin
>       return To_Ieee_Short_Real (Number).Exponent /= 255;
>    end Valid_Real;

It might make sense to use modular types instead of signed integer
types for Mantisse_Sign, Exponent, and Mantisse (or Mantissa, if you
want to use English); then you can use "and", "or", and "not"
operations to test bits.  Actually, I'd probably define a couple
constants here:

   Exponent_Size : constant := 8;
   Mantissa_Size : constant := 23;

   type Exponent_Type is mod 2 ** Exponent_Size;
   type Mantissa_Type is mod 2 ** Mantissa_Size;
   type Mantissa_Sign_Type is mod 2;

Using constants makes it easy to re-implement this for 64- and 80-bit
floats.

   type Ieee_Short_Real is
      record
         Mantissa_Sign : Mantissa_Sign_Type;
         Exponent      : Exponent_Type;
         Mantissa      : Mantissa_Type;
      end record;

(I've omitted the rep clause because I think the one above might work
only for big-endian and not little-endian machines or vice versa, and
I don't feel like figuring it out because I have a cold and my head
hurts enough already.)

Then, if X is the result of the Unchecked_Conversion:

Number is a valid float if X.Exponent /= Exponent_Type'Last

Number is an infinity if X.Exponent = Exponent_Type'Last and
X.Mantissa = 0

Number is a qNaN if X.Exponent = Exponent_Type'Last and
                    (X.Mantissa and 2**(Mantissa_Size-1) /= 0)

Number is a sNaN if X.Exponent = Exponent_Type'Last and X.Mantissa /=
0 and
                    (X.Mantissa and 2**(Mantissa_Size-1) = 0)

On the Pentium, Number is a "real indefinite" if
                    X.Exponent = Exponent_Type'Last and
                    X.Mantissa = 2**(Mantissa_Size-1)

Number is a denormal if X.Exponent = 0 and X.Mantissa /= 0

Hope this helps someone (and I hope I didn't screw up and get
something wrong),

                               -- Adam





^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: How to check a Float for NaN
  2008-05-06 22:18         ` Adam Beneschan
  2008-05-07 22:56           ` Randy Brukardt
@ 2008-05-07 22:56           ` Randy Brukardt
  2008-05-07 23:20             ` Adam Beneschan
  2008-05-09  7:24             ` Stephen Leake
  1 sibling, 2 replies; 51+ messages in thread
From: Randy Brukardt @ 2008-05-07 22:56 UTC (permalink / raw)


"Adam Beneschan" <adam@irvine.com> wrote in message 
news:95c1de75-7aa0-4f00-bbc4-6f503a3c7aef@b9g2000prh.googlegroups.com...
...
>   type Ieee_Short_Real is
>      record
>         Mantissa_Sign : Mantissa_Sign_Type;
>         Exponent      : Exponent_Type;
>         Mantissa      : Mantissa_Type;
>      end record;
>
> (I've omitted the rep clause because I think the one above might work
> only for big-endian and not little-endian machines or vice versa, and
> I don't feel like figuring it out because I have a cold and my head
> hurts enough already.)

Sorry about the cold, but if you omit the rep. clause, all of these 
components are likely to take full bytes and that won't work at all.

IF you had given size clauses on all of the modular types AND a pragma Pack 
on the record, it MIGHT have worked. But given that you need a particular 
representation, omitting the rep. clause is irrational. (That said, getting 
it right on both big-endian and little-endian machines is enough to make my 
head explode. But it's rarely necessary, and certainly isn't in the OP's 
case.)

                                 Randy.





^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: How to check a Float for NaN
  2008-05-06 22:18         ` Adam Beneschan
@ 2008-05-07 22:56           ` Randy Brukardt
  2008-05-07 22:56           ` Randy Brukardt
  1 sibling, 0 replies; 51+ messages in thread
From: Randy Brukardt @ 2008-05-07 22:56 UTC (permalink / raw)


"Adam Beneschan" <adam@irvine.com> wrote in message 
news:95c1de75-7aa0-4f00-bbc4-6f503a3c7aef@b9g2000prh.googlegroups.com...
...
>   type Ieee_Short_Real is
>      record
>         Mantissa_Sign : Mantissa_Sign_Type;
>         Exponent      : Exponent_Type;
>         Mantissa      : Mantissa_Type;
>      end record;
>
> (I've omitted the rep clause because I think the one above might work
> only for big-endian and not little-endian machines or vice versa, and
> I don't feel like figuring it out because I have a cold and my head
> hurts enough already.)

Sorry about the cold, but if you omit the rep. clause, all of these 
components are likely to take full bytes and that won't work at all.

IF you had given size clauses on all of the modular types AND a pragma Pack 
on the record, it MIGHT have worked. But given that you need a particular 
representation, omitting the rep. clause is irrational. (That said, getting 
it right on both big-endian and little-endian machines is enough to make my 
head explode. But it's rarely necessary, and certainly isn't in the OP's 
case.)

                                 Randy.





^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: How to check a Float for NaN
  2008-05-07 22:56           ` Randy Brukardt
@ 2008-05-07 23:20             ` Adam Beneschan
  2008-05-09  7:24             ` Stephen Leake
  1 sibling, 0 replies; 51+ messages in thread
From: Adam Beneschan @ 2008-05-07 23:20 UTC (permalink / raw)


On May 7, 3:56 pm, "Randy Brukardt" <ra...@rrsoftware.com> wrote:
> "Adam Beneschan" <a...@irvine.com> wrote in message
>
> news:95c1de75-7aa0-4f00-bbc4-6f503a3c7aef@b9g2000prh.googlegroups.com...
> ...
>
> >   type Ieee_Short_Real is
> >      record
> >         Mantissa_Sign : Mantissa_Sign_Type;
> >         Exponent      : Exponent_Type;
> >         Mantissa      : Mantissa_Type;
> >      end record;
>
> > (I've omitted the rep clause because I think the one above might work
> > only for big-endian and not little-endian machines or vice versa, and
> > I don't feel like figuring it out because I have a cold and my head
> > hurts enough already.)
>
> Sorry about the cold, but if you omit the rep. clause, all of these
> components are likely to take full bytes and that won't work at all.

I didn't mean that this would work without a rep clause.  I only meant
that I didn't feel like figuring it out (especially given that I
wanted to use the constants I defined instead of hard-coded integer
literals).  Yes, it does need one.  How about if I say, "Left as an
exercise for the reader"??

                               -- Adam




^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: How to check a Float for NaN
  2008-05-07 22:56           ` Randy Brukardt
  2008-05-07 23:20             ` Adam Beneschan
@ 2008-05-09  7:24             ` Stephen Leake
  1 sibling, 0 replies; 51+ messages in thread
From: Stephen Leake @ 2008-05-09  7:24 UTC (permalink / raw)


"Randy Brukardt" <randy@rrsoftware.com> writes:

> "Adam Beneschan" <adam@irvine.com> wrote in message 
> news:95c1de75-7aa0-4f00-bbc4-6f503a3c7aef@b9g2000prh.googlegroups.com...
> ...
>>   type Ieee_Short_Real is
>>      record
>>         Mantissa_Sign : Mantissa_Sign_Type;
>>         Exponent      : Exponent_Type;
>>         Mantissa      : Mantissa_Type;
>>      end record;
>>
>> (I've omitted the rep clause because I think the one above might work
>> only for big-endian and not little-endian machines or vice versa, and
>> I don't feel like figuring it out because I have a cold and my head
>> hurts enough already.)
>
> Sorry about the cold, but if you omit the rep. clause, all of these 
> components are likely to take full bytes and that won't work at all.
>
> IF you had given size clauses on all of the modular types AND a pragma Pack 
> on the record, it MIGHT have worked. But given that you need a particular 
> representation, omitting the rep. clause is irrational. (That said, getting 
> it right on both big-endian and little-endian machines is enough to make my 
> head explode. But it's rarely necessary, and certainly isn't in the OP's 
> case.)

Ada 2005 supports endian-independent rep clauses; LRM 13.5.3 9/2.

However, GNAT doesn't support them for anything bigger than 1 byte.

I don't know about other compilers.

-- 
-- Stephe



^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: How to check a Float for NaN
  2008-04-30 10:27 How to check a Float for NaN Jerry
                   ` (2 preceding siblings ...)
  2008-05-05 18:23 ` Martin Krischik
@ 2008-05-09 19:49 ` anon
  2008-05-10  2:36   ` Jerry
  3 siblings, 1 reply; 51+ messages in thread
From: anon @ 2008-05-09 19:49 UTC (permalink / raw)


  --
  -- Nan is define to be greater than value of hex 16#FF000000#
  -- 

  function isNan ( N : Float ) return Boolean is

     T : Long_Long_Integer := Long_Long_Integer ( N ) ;

    begin
      if T > 16#FF000000# then
        return True ;
      else
        return False ;
      end if ;
    end ;


In <3132e38d-18bb-4890-9cec-31056ac6e3ba@x19g2000prg.googlegroups.com>, Jerry <lanceboyle@qwest.net> writes:
>How would one check a Float or Long_Float if it has value NaN? The
>only ways that I can come up with are to import a C function (isnan, I
>think) or to write Long_Float'image(Some_Float) to a string and
>examine the first three characters to see if they are "NaN" (and that
>seems to be a GNAT implementation choice so might not be portable,
>which is OK for my use).
>
>Jerry
>




^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: How to check a Float for NaN
  2008-05-09 19:49 ` anon
@ 2008-05-10  2:36   ` Jerry
  2008-05-10  3:53     ` anon
  2008-05-10  8:05     ` Georg Bauhaus
  0 siblings, 2 replies; 51+ messages in thread
From: Jerry @ 2008-05-10  2:36 UTC (permalink / raw)


On May 9, 12:49 pm, a...@anon.org (anon) wrote:
>   --
>   -- Nan is define to be greater than value of hex 16#FF000000#
>   --
>
>   function isNan ( N : Float ) return Boolean is
>
>      T : Long_Long_Integer := Long_Long_Integer ( N ) ;
>
>     begin
>       if T > 16#FF000000# then
>         return True ;
>       else
>         return False ;
>       end if ;
>     end ;
>
> In <3132e38d-18bb-4890-9cec-31056ac6e...@x19g2000prg.googlegroups.com>, Jerry <lancebo...@qwest.net> writes:
>
> >How would one check a Float or Long_Float if it has value NaN? The
> >only ways that I can come up with are to import a C function (isnan, I
> >think) or to write Long_Float'image(Some_Float) to a string and
> >examine the first three characters to see if they are "NaN" (and that
> >seems to be a GNAT implementation choice so might not be portable,
> >which is OK for my use).
>
> >Jerry

No offense to anon, but does this work? Does anyone know of a
reference for this definition of a NaN?

Also, wondering how one might detect an Inf.

It seems that there is enough information in this thread to begin
writing a little package to deal with some of these things.

Thanks for all the great tips, BTW.

Jerry



^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: How to check a Float for NaN
  2008-05-10  2:36   ` Jerry
@ 2008-05-10  3:53     ` anon
  2008-05-10  6:24       ` christoph.grein
  2008-05-10  8:05     ` Georg Bauhaus
  1 sibling, 1 reply; 51+ messages in thread
From: anon @ 2008-05-10  3:53 UTC (permalink / raw)


Reference Microsoft and 

"isnan.asm" from 

http://www.visionlab.uncc.edu/websvn/filedetails.php?repname=toolchain&path=%2Fvendor%2Fvdsplibs%2Fcurrent%2Flibdsp%2Fisnan.asm&rev=1693&sc=1

The only mistake is that T > 16#7F000000# because I forgot to adjust 
for the the sign bit because NaN can have a valid sign set.

This work because in Intel the NaN is set by forcing bits 30-24 to 1 aka 
16#7F000000# 

The 
  T : Long_Long_Integer := Long_Long_Integer ( N ) ;
moves the bit-value of N a 48-bit float to a Long_Long_Integer (T)
without conversion. 



In <b42cb056-f923-45d9-9e01-d46d8376c41b@t12g2000prg.googlegroups.com>, Jerry <lanceboyle@qwest.net> writes:
>On May 9, 12:49=A0pm, a...@anon.org (anon) wrote:
>> =A0 --
>> =A0 -- Nan is define to be greater than value of hex 16#FF000000#
>> =A0 --
>>
>> =A0 function isNan ( N : Float ) return Boolean is
>>
>> =A0 =A0 =A0T : Long_Long_Integer :=3D Long_Long_Integer ( N ) ;
>>
>> =A0 =A0 begin
>> =A0 =A0 =A0 if T > 16#FF000000# then
>> =A0 =A0 =A0 =A0 return True ;
>> =A0 =A0 =A0 else
>> =A0 =A0 =A0 =A0 return False ;
>> =A0 =A0 =A0 end if ;
>> =A0 =A0 end ;
>>
>> In <3132e38d-18bb-4890-9cec-31056ac6e...@x19g2000prg.googlegroups.com>, Je=
>rry <lancebo...@qwest.net> writes:
>>
>> >How would one check a Float or Long_Float if it has value NaN? The
>> >only ways that I can come up with are to import a C function (isnan, I
>> >think) or to write Long_Float'image(Some_Float) to a string and
>> >examine the first three characters to see if they are "NaN" (and that
>> >seems to be a GNAT implementation choice so might not be portable,
>> >which is OK for my use).
>>
>> >Jerry
>
>No offense to anon, but does this work? Does anyone know of a
>reference for this definition of a NaN?
>
>Also, wondering how one might detect an Inf.
>
>It seems that there is enough information in this thread to begin
>writing a little package to deal with some of these things.
>
>Thanks for all the great tips, BTW.
>
>Jerry




^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: How to check a Float for NaN
  2008-05-10  3:53     ` anon
@ 2008-05-10  6:24       ` christoph.grein
  0 siblings, 0 replies; 51+ messages in thread
From: christoph.grein @ 2008-05-10  6:24 UTC (permalink / raw)


> T : Long_Long_Integer := Long_Long_Integer ( N ) ;

Anon, this is nonsense. What you present is a type conversion Float to
Long_Long_Integer, which will not work (it will round to the next
nearest integer value or raise Constraint_Error if the float value is
out of range). What is really needed and will work is an unchecked
conversion (this will leave all bits unchanged).



^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: How to check a Float for NaN
  2008-05-10  2:36   ` Jerry
  2008-05-10  3:53     ` anon
@ 2008-05-10  8:05     ` Georg Bauhaus
  1 sibling, 0 replies; 51+ messages in thread
From: Georg Bauhaus @ 2008-05-10  8:05 UTC (permalink / raw)


Jerry wrote:
> On May 9, 12:49 pm, a...@anon.org (anon) wrote:
>>   --
>>   -- Nan is define to be greater than value of hex 16#FF000000#
>>   --
>>
>>   function isNan ( N : Float ) return Boolean is
>>
>>      T : Long_Long_Integer := Long_Long_Integer ( N ) ;
>>
>>     begin
>>       if T > 16#FF000000# then
>>         return True ;
>>       else
>>         return False ;
>>       end if ;
>>     end ;
>>

> No offense to anon, but does this work? Does anyone know of a
> reference for this definition of a NaN?
> 
> Also, wondering how one might detect an Inf.
> 
> It seems that there is enough information in this thread to begin
> writing a little package to deal with some of these things.

I think you will need IEEE floats, not just Ada Floats.
(Some compilers have corresponding types, or implement their
Floats accordingly.) Consulting a text book again, I find that
IEEE defines representations for NaN (both quiet and signalling NaN),
Inf, ...

IIUC, for testing for NaN, basically

- ignore the sign bit
- expect all exponent bits set to 1
- expect the fraction part to be /= 0

This would explain why there are cases when an unchecked_conversion
of an IEEE FPT word to some "scalar word" will allow you to look
at the bits and decide whether it can represents a NaN.

Showing my ignorance I wonder, though, what happens when a fpt register
is effectively unchecked_converted into a CPU register suitable
for a long...



^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: How to check a Float for NaN
  2008-05-05 18:23 ` Martin Krischik
  2008-05-05 20:49   ` Adam Beneschan
@ 2008-05-10 17:00   ` anon
  2008-05-11 22:00     ` Keith Thompson
  1 sibling, 1 reply; 51+ messages in thread
From: anon @ 2008-05-10 17:00 UTC (permalink / raw)


If you look at my first post on this topic and change the 16#FF000000# 
to 16#7F000000# (typo, forgot to adjust for the sign-bit) its basically 
what I have done except that I use a 64-bit sign integer instead of the 
Unsigned_64.  In order to save coding time, did not want to add the
extra statements. Plus, if it for a final (it that time of the year) they 
should be able add those lines.

And because float is normally defined by the IEEE-754 as a 32-bit 
number it will fix into a 64-bit integer without raising a 
Constraint_Error.  The size of Long_Long_Integer is at least 64-bit 
signed integer on a 32/64 bit machines.

NaN := range 2#0111_1111_1111_0000_0000_0000_0000_0000# 
               ..
               2#1111_1111_1111_1111_1111_1111_1111_1111#  ;


In <12227360.svS57WvVVs@linux1.krischik.com>, Martin Krischik <krischik@users.sourceforge.net> writes:
>Jerry wrote:
>
>> How would one check a Float or Long_Float if it has value NaN? The
>> only ways that I can come up with are to import a C function (isnan, I
>> think) or to write Long_Float'image(Some_Float) to a string and
>> examine the first three characters to see if they are "NaN" (and that
>> seems to be a GNAT implementation choice so might not be portable,
>> which is OK for my use).
>
>How about an Unchecked Conversion to an Unsigned_64 and comparing
>>2#0111_1111_1111_0000_0000_0000_0000_0000#
>
>Note that it's '>' as 2#0111_1111_1111_0000_0000_0000_0000_0000# is positive
>infinity.
>
>Martin
>-- 
>mailto://krischik@users.sourceforge.net
>Ada programming at: http://ada.krischik.com




^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: How to check a Float for NaN
  2008-05-10 17:00   ` anon
@ 2008-05-11 22:00     ` Keith Thompson
  2008-05-12  2:01       ` anon
  0 siblings, 1 reply; 51+ messages in thread
From: Keith Thompson @ 2008-05-11 22:00 UTC (permalink / raw)


anon@anon.org (anon) writes:
> If you look at my first post on this topic and change the 16#FF000000# 
> to 16#7F000000# (typo, forgot to adjust for the sign-bit) its basically 
> what I have done except that I use a 64-bit sign integer instead of the 
> Unsigned_64.  In order to save coding time, did not want to add the
> extra statements. Plus, if it for a final (it that time of the year) they 
> should be able add those lines.
[...]

You're using a value conversion.  This converts, for example, the
Float value 3.0 to the Long_Long_Integer value 3.  In your code, with
16#FF000000# changed to 16#7F000000#, this:

    T : Long_Long_Integer := Long_Long_Integer ( N ) ;
    ...
    if T > 16#7F000000# then
    ...

is essentially equivalent to this:

    if T > 2130706432.0 then

Try isNan(2.0E9) and isNan(3.0E9).

You need an Unchecked_Conversion.  You also need to make sure you
choose a floating-point and integer type of the same size, and to
allow for things like byte ordering (even if you're limiting the test
to systems that support IEEE floating-point, which is probably a
reasonable restriction since other floating-point formats may not
support NaNs at all).

-- 
Keith Thompson (The_Other_Keith) <kst-u@mib.org>
Nokia
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"



^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: How to check a Float for NaN
  2008-05-11 22:00     ` Keith Thompson
@ 2008-05-12  2:01       ` anon
  0 siblings, 0 replies; 51+ messages in thread
From: anon @ 2008-05-12  2:01 UTC (permalink / raw)


If you read I answered that! 

>> In order to save coding time, did not want to add the
>> extra statements. Plus, if it for a final (it that time of the year) they 
>> should be able add those lines.

Last week was FINALS WEEK for most colleges.  If you answer a question 
durring this time you NEVER give the complete answer only a partial one. 
And it does not matter if the answer is in code or a couple of paragraphs.

My answer was just that, correct in the outline but not is uncomplete.  And 
any Ada programmer should be able to take my program and make it work 
within a minute or two. But a college student at finals would never spend 
the time, they want the complete and only complete answer, so they can 
study for other classes or party.



n <87wsm0o608.fsf@kvetch.smov.org>, Keith Thompson <kst-u@mib.org> writes:
>anon@anon.org (anon) writes:
>> If you look at my first post on this topic and change the 16#FF000000# 
>> to 16#7F000000# (typo, forgot to adjust for the sign-bit) its basically 
>> what I have done except that I use a 64-bit sign integer instead of the 
>> Unsigned_64.  In order to save coding time, did not want to add the
>> extra statements. Plus, if it for a final (it that time of the year) they 
>> should be able add those lines.
>[...]
>
>You're using a value conversion.  This converts, for example, the
>Float value 3.0 to the Long_Long_Integer value 3.  In your code, with
>16#FF000000# changed to 16#7F000000#, this:
>
>    T : Long_Long_Integer := Long_Long_Integer ( N ) ;
>    ...
>    if T > 16#7F000000# then
>    ...
>
>is essentially equivalent to this:
>
>    if T > 2130706432.0 then
>
>Try isNan(2.0E9) and isNan(3.0E9).
>
>You need an Unchecked_Conversion.  You also need to make sure you
>choose a floating-point and integer type of the same size, and to
>allow for things like byte ordering (even if you're limiting the test
>to systems that support IEEE floating-point, which is probably a
>reasonable restriction since other floating-point formats may not
>support NaNs at all).
>
>-- 
>Keith Thompson (The_Other_Keith) <kst-u@mib.org>
>Nokia
>"We must do something.  This is something.  Therefore, we must do this."
>    -- Antony Jay and Jonathan Lynn, "Yes Minister"




^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: How to check a Float for NaN
  2008-04-30 20:36 ` Jerry
  2008-04-30 21:53   ` Adam Beneschan
@ 2014-05-22  7:27   ` jan.de.kruyf
  2014-05-22  8:09     ` Dmitry A. Kazakov
  1 sibling, 1 reply; 51+ messages in thread
From: jan.de.kruyf @ 2014-05-22  7:27 UTC (permalink / raw)


On Wednesday, April 30, 2008 10:36:21 PM UTC+2, Jerry wrote:

> 
> Check this out:
> 
> function Is_NaN(x : Long_Float) return Boolean is
> begin
>     return x /= x;
> end Is_NaN;
> 
> A couple of minutes on Wikipedia saves the day. From
> http://en.wikipedia.org/wiki/NaN#NaN_encodings:
> 
> "A NaN does not compare equal to any floating-point number or NaN,
> even if the latter has an identical representation. One can therefore
> test whether a variable has a NaN value by comparing it to itself."
> 
> Jerry

This worked on the Gnat compiler, this code

      if Cos_Theta /= Cos_Theta then
	 Gct.Trace (Debug_Str, "cos_theta is NaN******");
      else
	 Gct.Trace (Debug_Str, "cos_theta : " & Long_Float'Image (Cos_Theta)); 
      end if;

gives this in the log:

[MATH3D.DEBUG] 1/372 cos_theta is NaN****** (2014-05-22 09:23:24.155)(loc: math3d.adb:129)

Hope it helps someone;

Cheers,

j.


^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: How to check a Float for NaN
  2014-05-22  7:27   ` jan.de.kruyf
@ 2014-05-22  8:09     ` Dmitry A. Kazakov
  2014-05-22  9:24       ` Simon Wright
  0 siblings, 1 reply; 51+ messages in thread
From: Dmitry A. Kazakov @ 2014-05-22  8:09 UTC (permalink / raw)


On Thu, 22 May 2014 00:27:02 -0700 (PDT), jan.de.kruyf@gmail.com wrote:

> On Wednesday, April 30, 2008 10:36:21 PM UTC+2, Jerry wrote:
> 
>> 
>> Check this out:
>> 
>> function Is_NaN(x : Long_Float) return Boolean is
>> begin
>>     return x /= x;
>> end Is_NaN;
>> 
>> A couple of minutes on Wikipedia saves the day. From
>> http://en.wikipedia.org/wiki/NaN#NaN_encodings:
>> 
>> "A NaN does not compare equal to any floating-point number or NaN,
>> even if the latter has an identical representation. One can therefore
>> test whether a variable has a NaN value by comparing it to itself."
>> 
>> Jerry
> 
> This worked on the Gnat compiler, this code
> 
>       if Cos_Theta /= Cos_Theta then
> 	 Gct.Trace (Debug_Str, "cos_theta is NaN******");
>       else
> 	 Gct.Trace (Debug_Str, "cos_theta : " & Long_Float'Image (Cos_Theta)); 
>       end if;
> 
> gives this in the log:
> 
> [MATH3D.DEBUG] 1/372 cos_theta is NaN****** (2014-05-22 09:23:24.155)(loc: math3d.adb:129)
> 
> Hope it helps someone;

You could simply use range check:

   X in Long_Float'Range

NaN is not a number and thus outside the range.

However, for technical computations, it is advisory to turn IEEE semantics
off. Fortunately there is a very simple way to do so in Ada:

   subtype Real_Long_Float is Long_Float range Long_Float'Range;

Use this instead of Long_Float and you will never have NaN, +/-Inf again.
Constraint_Error will propagate instead.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de


^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: How to check a Float for NaN
  2014-05-22  8:09     ` Dmitry A. Kazakov
@ 2014-05-22  9:24       ` Simon Wright
  2014-05-22  9:48         ` Dmitry A. Kazakov
  0 siblings, 1 reply; 51+ messages in thread
From: Simon Wright @ 2014-05-22  9:24 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:

> On Thu, 22 May 2014 00:27:02 -0700 (PDT), jan.de.kruyf@gmail.com wrote:

>>       if Cos_Theta /= Cos_Theta then
>> 	 Gct.Trace (Debug_Str, "cos_theta is NaN******");
>>       else
>> 	 Gct.Trace (Debug_Str, "cos_theta : " & Long_Float'Image (Cos_Theta)); 
>>       end if;
>> 
>> gives this in the log:
>> 
>> [MATH3D.DEBUG] 1/372 cos_theta is NaN****** (2014-05-22 09:23:24.155)(loc: math3d.adb:129)
>> 
>> Hope it helps someone;
>
> You could simply use range check:
>
>    X in Long_Float'Range
>
> NaN is not a number and thus outside the range.

This would also return False for +/-Inf, so if the OP wants specifically
to check for NaN it wouldn't do. Can't think why they would, though.

GNAT says about "X in Long_Float'Range"
   inf.adb:10:60: warning: explicit membership test may be optimized away
   inf.adb:10:60: warning: use 'Valid attribute instead

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: How to check a Float for NaN
  2014-05-22  9:24       ` Simon Wright
@ 2014-05-22  9:48         ` Dmitry A. Kazakov
  2014-05-22 15:28           ` Adam Beneschan
  0 siblings, 1 reply; 51+ messages in thread
From: Dmitry A. Kazakov @ 2014-05-22  9:48 UTC (permalink / raw)


On Thu, 22 May 2014 10:24:35 +0100, Simon Wright wrote:

> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
> 
>> On Thu, 22 May 2014 00:27:02 -0700 (PDT), jan.de.kruyf@gmail.com wrote:
> 
>>>       if Cos_Theta /= Cos_Theta then
>>> 	 Gct.Trace (Debug_Str, "cos_theta is NaN******");
>>>       else
>>> 	 Gct.Trace (Debug_Str, "cos_theta : " & Long_Float'Image (Cos_Theta)); 
>>>       end if;
>>> 
>>> gives this in the log:
>>> 
>>> [MATH3D.DEBUG] 1/372 cos_theta is NaN****** (2014-05-22 09:23:24.155)(loc: math3d.adb:129)
>>> 
>>> Hope it helps someone;
>>
>> You could simply use range check:
>>
>>    X in Long_Float'Range
>>
>> NaN is not a number and thus outside the range.
> 
> This would also return False for +/-Inf, so if the OP wants specifically
> to check for NaN it wouldn't do. Can't think why they would, though.
> 
> GNAT says about "X in Long_Float'Range"
>    inf.adb:10:60: warning: explicit membership test may be optimized away

Looks like a bug, it may not be optimized away if Long_Float is IEEE 754.

>    inf.adb:10:60: warning: use 'Valid attribute instead

Hmm, reading RM 13.9.2 makes me believe that NaN's 'Valid should yield
True.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de


^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: How to check a Float for NaN
  2014-05-22  9:48         ` Dmitry A. Kazakov
@ 2014-05-22 15:28           ` Adam Beneschan
  2014-05-22 16:31             ` Dmitry A. Kazakov
  0 siblings, 1 reply; 51+ messages in thread
From: Adam Beneschan @ 2014-05-22 15:28 UTC (permalink / raw)


On Thursday, May 22, 2014 2:48:47 AM UTC-7, Dmitry A. Kazakov wrote:
> On Thu, 22 May 2014 10:24:35 +0100, Simon Wright wrote:
> 
> > "Dmitry A. Kazakov" writes:
> 
> >> On Thu, 22 May 2014 00:27:02 -0700 (PDT), jan.de.kruyf wrote:

> >>>       if Cos_Theta /= Cos_Theta then
> 
> >>> 	 Gct.Trace (Debug_Str, "cos_theta is NaN******");
> 
> >>>       else
> 
> >>> 	 Gct.Trace (Debug_Str, "cos_theta : " & Long_Float'Image (Cos_Theta)); 
> 
> >>>       end if;
> 
> >>> 
> 
> >>> gives this in the log:
> 
> >>> 
> 
> >>> [MATH3D.DEBUG] 1/372 cos_theta is NaN****** (2014-05-22 09:23:24.155)(loc: math3d.adb:129)
> 
> >>> 
> 
> >>> Hope it helps someone;
> 
> >>
> 
> >> You could simply use range check:

> >>    X in Long_Float'Range

> >> NaN is not a number and thus outside the range.

> > This would also return False for +/-Inf, so if the OP wants specifically
> > to check for NaN it wouldn't do. Can't think why they would, though.

> > GNAT says about "X in Long_Float'Range"
> 
> >    inf.adb:10:60: warning: explicit membership test may be optimized away

> Looks like a bug, it may not be optimized away if Long_Float is IEEE 754.

> >    inf.adb:10:60: warning: use 'Valid attribute instead
 
> Hmm, reading RM 13.9.2 makes me believe that NaN's 'Valid should yield
> True.

No, I don't think so.  3.5.7(8) says "The set of values for a floating point type is the (infinite) set of rational numbers."  This excludes NaN and infinities, which are not rational numbers (nor any kind of number).  Therefore, if X contains an infinity or NaN, X'Valid should be false.

Unlike some languages (e.g. Java), Ada doesn't define +/- Infinity or NaN to be valid values in the language, and therefore it can't make any statements about how they're supposed to be handled.  Normally, an operation that results in infinity or NaN is supposed to raise Constraint_Error.  However, the language allows for implementations not to check this, by providing a Machine_Overflows attribute that is False if Constraint_Error isn't raised.  As far as I can tell, however, the language doesn't say anything about what happens otherwise, except that the result is "unspecified" or "implementation-defined".  Even where an implementation is required to support IEEE 754 semantics (I think this is required if an implementation claims to support Annex G), I don't believe the requirements apply to NaN or Infinity even if Machine_Overflows is False--since those aren't really valid values in the language, I don't think the language can impose any requirements on how they're handled.

In particular, that means that a condition like

    if Cos_Theta /= Cos_Theta then ...

could be treated the same as

    if False then ...

by the compiler.  And yes, "X in Long_Float'Range" could be treated as "known to be True".  Maybe it will and maybe it won't, but the thing is, you can't count on it in Ada.  You may be able to count on it for a specific compiler, depending on what the compiler vendor promises.  But it won't be portable.  (The warning could be a GNAT bug within the context of what GNAT's documentation says the compiler should do--I don't know, I haven't read all of it--but this behavior is permissible in Ada.)

There are a few statements in the AARM that say "It is anticipated that an Ada binding to IEC 559:1989 will be developed in the future" or something similar, and those sections do discuss treating infinities and NaN's as values and anticipate that there will be language rules about how they're to be handled.  However, I notice that those statements were in the Ada 95 AARM and haven't really been changed since.  On Google Groups, this thread includes some posts going back to 2008 about this subject, including one by Randy about why the ARG hasn't addressed this yet.

                                   -- Adam





^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: How to check a Float for NaN
  2014-05-22 15:28           ` Adam Beneschan
@ 2014-05-22 16:31             ` Dmitry A. Kazakov
  2014-05-22 23:33               ` Adam Beneschan
  0 siblings, 1 reply; 51+ messages in thread
From: Dmitry A. Kazakov @ 2014-05-22 16:31 UTC (permalink / raw)


On Thu, 22 May 2014 08:28:33 -0700 (PDT), Adam Beneschan wrote:

> On Thursday, May 22, 2014 2:48:47 AM UTC-7, Dmitry A. Kazakov wrote:
>> On Thu, 22 May 2014 10:24:35 +0100, Simon Wright wrote:
>> 
>>> "Dmitry A. Kazakov" writes:
>> 
>>>> On Thu, 22 May 2014 00:27:02 -0700 (PDT), jan.de.kruyf wrote:
> 
>>>>>       if Cos_Theta /= Cos_Theta then
>> 
>>>>> 	 Gct.Trace (Debug_Str, "cos_theta is NaN******");
>> 
>>>>>       else
>> 
>>>>> 	 Gct.Trace (Debug_Str, "cos_theta : " & Long_Float'Image (Cos_Theta)); 
>> 
>>>>>       end if;
>> 
>>>>> 
>> 
>>>>> gives this in the log:
>> 
>>>>> 
>> 
>>>>> [MATH3D.DEBUG] 1/372 cos_theta is NaN****** (2014-05-22 09:23:24.155)(loc: math3d.adb:129)
>> 
>>>>> 
>> 
>>>>> Hope it helps someone;
>> 
>>>>
>> 
>>>> You could simply use range check:
> 
>>>>    X in Long_Float'Range
> 
>>>> NaN is not a number and thus outside the range.
> 
>>> This would also return False for +/-Inf, so if the OP wants specifically
>>> to check for NaN it wouldn't do. Can't think why they would, though.
> 
>>> GNAT says about "X in Long_Float'Range"
>> 
>>>    inf.adb:10:60: warning: explicit membership test may be optimized away
> 
>> Looks like a bug, it may not be optimized away if Long_Float is IEEE 754.
> 
>>>    inf.adb:10:60: warning: use 'Valid attribute instead
>  
>> Hmm, reading RM 13.9.2 makes me believe that NaN's 'Valid should yield
>> True.
> 
> No, I don't think so.  3.5.7(8) says "The set of values for a floating
> point type is the (infinite) set of rational numbers."  This excludes NaN
> and infinities, which are not rational numbers (nor any kind of number).

These are not values of Long_Float. I guess that values of Long_Float are
"machine numbers" defined in the following sentence.

Why doesn't it preclude NaN returned and accepted by arithmetic operations?
Either 3.5.7 lies or the operations do.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: How to check a Float for NaN
  2014-05-22 16:31             ` Dmitry A. Kazakov
@ 2014-05-22 23:33               ` Adam Beneschan
  2014-05-23  7:38                 ` Dmitry A. Kazakov
  2014-05-23 21:39                 ` Randy Brukardt
  0 siblings, 2 replies; 51+ messages in thread
From: Adam Beneschan @ 2014-05-22 23:33 UTC (permalink / raw)


On Thursday, May 22, 2014 9:31:12 AM UTC-7, Dmitry A. Kazakov wrote:

> > No, I don't think so.  3.5.7(8) says "The set of values for a floating
> > point type is the (infinite) set of rational numbers."  This excludes NaN
> > and infinities, which are not rational numbers (nor any kind of number).
> 
> These are not values of Long_Float. I guess that values of Long_Float are
> "machine numbers" defined in the following sentence.

I'm not sure why the RM defined the "set of values" to be an infinite set; I'm sure that this made the rest of the semantics easier to specify in some way, but I don't know what that is.  The set of *machine numbers* for a type is a subset of this set of values.  I think that intermediate computations can involve numbers that aren't machine numbers (if they're performed using a type with greater precision, for example); I'm not sure.  In any case, though, it's clear that infinities and NaN aren't part of the "set of values", and thus they can't be part of the set of machine numbers which is a subset of the "set of values".


> Why doesn't it preclude NaN returned and accepted by arithmetic operations? 
> Either 3.5.7 lies or the operations do.

I think it *does* preclude NaN, unless I don't understand what you mean.  I guess you could say that the "operations lie", because if Machine_Overflows is False, an operation on two values of a floating-point type may have an invalid result.  Normally, that's not supposed to happen.  But we can consider Machine_Overflows=False to work somewhat similarly to a Suppress pragma in that undefined results may happen.  If B is a Boolean variable whose value is True, what does B := Boolean'Succ(B) do if Suppress(Range_Check) is in effect?  It will quite possibly set B to something that is not a valid Boolean value.  But I'm not sure that means the 'Succ operation is lying.  And I don't think that the arithmetic operations "lie" any more than 'Succ is in this example.

                                 -- Adam

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: How to check a Float for NaN
  2014-05-22 23:33               ` Adam Beneschan
@ 2014-05-23  7:38                 ` Dmitry A. Kazakov
  2014-05-23 21:39                 ` Randy Brukardt
  1 sibling, 0 replies; 51+ messages in thread
From: Dmitry A. Kazakov @ 2014-05-23  7:38 UTC (permalink / raw)


On Thu, 22 May 2014 16:33:50 -0700 (PDT), Adam Beneschan wrote:

> On Thursday, May 22, 2014 9:31:12 AM UTC-7, Dmitry A. Kazakov wrote:
> 
>>> No, I don't think so.  3.5.7(8) says "The set of values for a floating
>>> point type is the (infinite) set of rational numbers."  This excludes NaN
>>> and infinities, which are not rational numbers (nor any kind of number).
>> 
>> These are not values of Long_Float. I guess that values of Long_Float are
>> "machine numbers" defined in the following sentence.
> 
> I'm not sure why the RM defined the "set of values" to be an infinite set;
> I'm sure that this made the rest of the semantics easier to specify in
> some way, but I don't know what that is.  The set of *machine numbers* for
> a type is a subset of this set of values.  I think that intermediate
> computations can involve numbers that aren't machine numbers (if they're
> performed using a type with greater precision, for example); I'm not sure. 
> In any case, though, it's clear that infinities and NaN aren't part of the
> "set of values", and thus they can't be part of the set of machine numbers
> which is a subset of the "set of values".

Yes, but NaN is certainly a machine value of IEEE 754 hardware.

My impression is that the text was written prior to wide spread of IEEE 754
hardware and was not reviewed since.

>> Why doesn't it preclude NaN returned and accepted by arithmetic operations? 
>> Either 3.5.7 lies or the operations do.
> 
> I think it *does* preclude NaN, unless I don't understand what you mean. 
> I guess you could say that the "operations lie", because if
> Machine_Overflows is False, an operation on two values of a floating-point
> type may have an invalid result.

Yes, but an invalid result still may not be outside the set of type values!

If NaN is not a type value, then an operation returning NaN is not of the
type. It is a type error then, a compiler/language bug.

After all, floating-point types are models, there is no reason why a model
could not have ideals NaN, +/-Inf as proper values and thus arithmetic
operations were defined in terms of this extended set of values. Which is
what IEEE 754 actually is all about.

The semantics of X'Value to exclude IEEE ideals could be easily defined in
13.9.2 as a special case. (X'Succ and X'Pred are already defined correctly
as returning a machine number.)

3.5.7 could be slightly rewritten to convey that type values include
equivalents of some real numbers (machine numbers) and, possibly, of some
ideals (machine special values).

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de


^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: How to check a Float for NaN
  2014-05-22 23:33               ` Adam Beneschan
  2014-05-23  7:38                 ` Dmitry A. Kazakov
@ 2014-05-23 21:39                 ` Randy Brukardt
  2014-05-27  8:35                   ` Dmitry A. Kazakov
  2014-05-27 12:35                   ` Maurizio Tomasi
  1 sibling, 2 replies; 51+ messages in thread
From: Randy Brukardt @ 2014-05-23 21:39 UTC (permalink / raw)


"Adam Beneschan" <adambeneschan@gmail.com> wrote in message 
news:b96fb365-9061-4170-8824-f68bab37f9dc@googlegroups.com...
...
>> Why doesn't it preclude NaN returned and accepted by arithmetic 
>> operations?
>> Either 3.5.7 lies or the operations do.
>
>I think it *does* preclude NaN, unless I don't understand what you mean.  I 
>guess you could
>say that the "operations lie", because if Machine_Overflows is False, an 
>operation on two
>values of a floating-point type may have an invalid result.

Right. I have no idea what's supposed to happen if Machine_Overflows is 
False. To the point that Janus/Ada simply doesn't use it; Machine_Overflows 
is True and we check after every group of operations to ensure that's true. 
So it's not possible to generate a NaN in Janus/Ada. I understand that the 
other semantics exists, but it's a mess by any standard and I'd need a lot 
more convincing ($$$$) to support something else. [That is, I see no 
sensible reason for NaNs or infinities -- they're just ways of deferring 
detection of bugs. I would have hoped that Ada's moved beyond that, just 
like it has for integers.]

                                 Randy.


^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: How to check a Float for NaN
  2014-05-23 21:39                 ` Randy Brukardt
@ 2014-05-27  8:35                   ` Dmitry A. Kazakov
  2014-05-27 12:35                   ` Maurizio Tomasi
  1 sibling, 0 replies; 51+ messages in thread
From: Dmitry A. Kazakov @ 2014-05-27  8:35 UTC (permalink / raw)


On Fri, 23 May 2014 16:39:54 -0500, Randy Brukardt wrote:

> That is, I see no 
> sensible reason for NaNs or infinities -- they're just ways of deferring 
> detection of bugs. I would have hoped that Ada's moved beyond that, just 
> like it has for integers.]

Yes, from the engineering POV IEEE 754 is a great nuisance, as we want to
report any bugs as early as possible.

But as a mathematical construct (extended numeric sets) it is very elegant,
e.g. surreal numbers:

http://en.wikipedia.org/wiki/Surreal_number 

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: How to check a Float for NaN
  2014-05-23 21:39                 ` Randy Brukardt
  2014-05-27  8:35                   ` Dmitry A. Kazakov
@ 2014-05-27 12:35                   ` Maurizio Tomasi
  2014-05-27 15:53                     ` Adam Beneschan
  1 sibling, 1 reply; 51+ messages in thread
From: Maurizio Tomasi @ 2014-05-27 12:35 UTC (permalink / raw)


> That is, I see no sensible reason for NaNs or infinities -- they're just ways of deferring detection of bugs. I would have hoped that Ada's moved beyond that, just like it has for integers.]

Being a scientist working with large chunks of data, I find NaNs useful in a number of situations. I work in a domain (observational cosmology) where we need to deal with sky maps containing ~10^7 pixels (you can think of a "map" as a 1D vector where pixels on the sky sphere are ordered according to some rule). Not every sky direction can be sampled, because of a number of problems (in the instrument, in the observational strategy, in the data reduction pipeline, etc.)

Therefore, in my Python+NumPy codes I always mark such directions using "quiet NaNs". If I have to combine two maps in order e.g. to take their average, the usual rules for combining NaNs are be exactly what I want. Writing in Ada what I actually write in Python:

  for I := 1 to N do
    Average_Map(I) := 0.5 * (Map1(I) + Map2(I));
  end loop;

If either Map1(I) or Map2(I) (or both) are NaN, then Average_Map(I) will be a NaN too, which is correct from the point of view of the meaning of the measurement. But without proper treatment of NaNs, one should write

  for I in Map1'Range do
    if not Is_NaN(Map1(I)) and not Is_NaN(Map2(I)) then
      Average_Map(I) := 0.5 * (Map1(I) + Map2(I));
    else
      Set_To_NaN(Average_Map, I);
    end if;
  end loop;

If one has to run many calculations on such maps (which is indeed always the case) instead of just a plain average, the code can get quite complex. And I do not think one gets more safety from such verbosity, as what a scientist expects from a NaN number is actually what the usual rules for NaN give.

I am not an Ada export, so these are just my two cents,
  Maurizio.


^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: How to check a Float for NaN
  2014-05-27 12:35                   ` Maurizio Tomasi
@ 2014-05-27 15:53                     ` Adam Beneschan
  2014-05-27 22:35                       ` Randy Brukardt
  2014-05-28  8:40                       ` Maurizio Tomasi
  0 siblings, 2 replies; 51+ messages in thread
From: Adam Beneschan @ 2014-05-27 15:53 UTC (permalink / raw)


On Tuesday, May 27, 2014 5:35:26 AM UTC-7, Maurizio Tomasi wrote:
> > That is, I see no sensible reason for NaNs or infinities -- they're just ways of deferring detection of bugs. I would have hoped that Ada's moved beyond that, just like it has for integers.]
> 
> 
> 
> Being a scientist working with large chunks of data, I find NaNs useful in a number of situations. I work in a domain (observational cosmology) where we need to deal with sky maps containing ~10^7 pixels (you can think of a "map" as a 1D vector where pixels on the sky sphere are ordered according to some rule). Not every sky direction can be sampled, because of a number of problems (in the instrument, in the observational strategy, in the data reduction pipeline, etc.)
> 
> 
> 
> Therefore, in my Python+NumPy codes I always mark such directions using "quiet NaNs". If I have to combine two maps in order e.g. to take their average, the usual rules for combining NaNs are be exactly what I want. Writing in Ada what I actually write in Python:
> 
>   for I := 1 to N do
>     Average_Map(I) := 0.5 * (Map1(I) + Map2(I));
>   end loop;

Well, that's actually half Pascal and half Ada, but we understand what you mean.

But you don't need NaN's built into the language in order to get that sort of functionality.  In Ada (or C++ or any other language that supports operator overloading), it's simple enough to define an "optional floating-point" record type consisting of a float and a Boolean, where the Boolean indicates "missing data", and define operators that produce "missing data" if either operand is missing.  So you could still write mostly the same code, except that converting to or from a float, or from a floating-point literal, takes a little extra code.  

                              -- Adam

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: How to check a Float for NaN
  2014-05-27 15:53                     ` Adam Beneschan
@ 2014-05-27 22:35                       ` Randy Brukardt
  2014-05-27 22:59                         ` Jeffrey Carter
  2014-05-28  7:32                         ` Dmitry A. Kazakov
  2014-05-28  8:40                       ` Maurizio Tomasi
  1 sibling, 2 replies; 51+ messages in thread
From: Randy Brukardt @ 2014-05-27 22:35 UTC (permalink / raw)


"Adam Beneschan" <adambeneschan@gmail.com> wrote in message 
news:840855a9-bda8-44b7-ab53-e157b4fc1d31@googlegroups.com...
On Tuesday, May 27, 2014 5:35:26 AM UTC-7, Maurizio Tomasi wrote:
>> > That is, I see no sensible reason for NaNs or infinities -- they're 
>> > just ways of deferring detection of bugs. I would have hoped that Ada's 
>> > moved beyond that, just like it has for integers.]
>>
>>
>>
>> Being a scientist working with large chunks of data, I find NaNs useful 
>> in a number of situations.
>> I work in a domain (observational cosmology) where we need to deal with 
>> sky maps containing
>> ~10^7 pixels (you can think of a "map" as a 1D vector where pixels on the 
>> sky sphere are
>> ordered according to some rule). Not every sky direction can be sampled, 
>> because of a number
>> of problems (in the instrument, in the observational strategy, in the 
>> data reduction pipeline, etc.)
>>
>> Therefore, in my Python+NumPy codes I always mark such directions using 
>> "quiet NaNs".
>> If I have to combine two maps in order e.g. to take their average, the 
>> usual rules for
>> combining NaNs are be exactly what I want. Writing in Ada what I actually 
>> write in Python:
>>
>>   for I := 1 to N do
>>     Average_Map(I) := 0.5 * (Map1(I) + Map2(I));
>>   end loop;
>
>Well, that's actually half Pascal and half Ada, but we understand what you 
>mean.
>
>But you don't need NaN's built into the language in order to get that sort 
>of functionality.  In
>Ada (or C++ or any other language that supports operator overloading), it's 
>simple enough
>to define an "optional floating-point" record type consisting of a float 
>and a Boolean, where
>the Boolean indicates "missing data", and define operators that produce 
>"missing data" if
>either operand is missing.  So you could still write mostly the same code, 
>except that
>converting to or from a float, or from a floating-point literal, takes a 
>little extra code.

If one has
    function "+" (Right : Float) return Optional_Float;

then the "extra code" is just preceeding the float value with a "+". Hardly 
earth-shaking. (And the usual complaint about using "+" as a conversion 
operator is a non-problem here as these are numeric types).

I much prefer this sort of solution (where the missing values are explicitly 
treated) rather than using some sort of magic number (a NaN being an extreme 
version of that). The name alone tells you that it doesn't belong in a 
numeric type -- since when is something that is "not a number" belong in a 
type defining numbers?

As usual, this is mainly a case of premature optimization (preverting the 
hardware to handle something that's a rare need -- I wonder how much faster 
float hardware could be if it didn't have to mess with NaNs? I know that 
they impacted our software floating point quite a bit even though I made no 
attempt to actually do anything useful with them.)

                                 Randy.


^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: How to check a Float for NaN
  2014-05-27 22:35                       ` Randy Brukardt
@ 2014-05-27 22:59                         ` Jeffrey Carter
  2014-05-28  7:32                         ` Dmitry A. Kazakov
  1 sibling, 0 replies; 51+ messages in thread
From: Jeffrey Carter @ 2014-05-27 22:59 UTC (permalink / raw)


On 05/27/2014 03:35 PM, Randy Brukardt wrote:
>
> I much prefer this sort of solution (where the missing values are explicitly
> treated) rather than using some sort of magic number (a NaN being an extreme
> version of that). The name alone tells you that it doesn't belong in a
> numeric type -- since when is something that is "not a number" belong in a
> type defining numbers?

It's a clear violation of the software-engineering principle that a value has 
only a single meaning. (Of course, returning zero from Ada.Strings.Fixed.Index 
is the same error.)

-- 
Jeff Carter
"There's no messiah here. There's a mess all right, but no messiah."
Monty Python's Life of Brian
84


^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: How to check a Float for NaN
  2014-05-27 22:35                       ` Randy Brukardt
  2014-05-27 22:59                         ` Jeffrey Carter
@ 2014-05-28  7:32                         ` Dmitry A. Kazakov
  1 sibling, 0 replies; 51+ messages in thread
From: Dmitry A. Kazakov @ 2014-05-28  7:32 UTC (permalink / raw)


On Tue, 27 May 2014 17:35:48 -0500, Randy Brukardt wrote:

> As usual, this is mainly a case of premature optimization (preverting the 
> hardware to handle something that's a rare need -- I wonder how much faster 
> float hardware could be if it didn't have to mess with NaNs?

BTW, the poster mentioned it was in Python, which implies that performance
couldn't be any concern!

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: How to check a Float for NaN
  2014-05-27 15:53                     ` Adam Beneschan
  2014-05-27 22:35                       ` Randy Brukardt
@ 2014-05-28  8:40                       ` Maurizio Tomasi
  1 sibling, 0 replies; 51+ messages in thread
From: Maurizio Tomasi @ 2014-05-28  8:40 UTC (permalink / raw)


> But you don't need NaN's built into the language in order to get that sort of functionality.  In Ada (or C++ or any other language that supports operator overloading), it's simple enough to define an "optional floating-point" record type consisting of a float and a Boolean, where the Boolean indicates "missing data", and define operators that produce "missing data" if either operand is missing.  So you could still write mostly the same code, except that converting to or from a float, or from a floating-point literal, takes a little extra code.  

Thanks a lot for your reply, I wrote my post with the hope of getting some good advice about the best way to do such things in Ada. Yours is indeed a smart idea!

Funny that I have used C++ and operator overloading for years, yet I have never realized that some sort of ad-hoc type (plus operator overloading) would be perfect here. Guess the reason is because I have used Python too much: to get a reasonable speed in such calculations, you are forced to use functions like numpy.add (http://docs.scipy.org/doc/numpy/reference/generated/numpy.add.html), which only accept basic numeric types.

Cheers,
  Maurizio.

(BTW, to answer Dmitry, speed *is* a concern for my calculations, which often involve Fourier Transforms on the maps and heavy Monte Carlo simulations. But fortunately functions like numpy.add are not that slow, as they are written in C/Fortran.)


^ permalink raw reply	[flat|nested] 51+ messages in thread

end of thread, other threads:[~2014-05-28  8:40 UTC | newest]

Thread overview: 51+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-04-30 10:27 How to check a Float for NaN Jerry
2008-04-30 10:47 ` christoph.grein
2008-04-30 10:50   ` christoph.grein
2008-04-30 15:02     ` Adam Beneschan
2008-04-30 20:33       ` Jerry
2008-04-30 23:23         ` Adam Beneschan
2008-05-01  1:00           ` Adam Beneschan
2008-05-01 19:52             ` Keith Thompson
2008-05-01 23:57               ` Jerry
2008-04-30 23:29       ` Randy Brukardt
2008-05-01  8:04       ` Stuart
2008-05-01 14:38         ` Adam Beneschan
2008-05-01 17:14           ` Stuart
2008-05-01 19:22             ` Randy Brukardt
2008-05-02  0:04         ` Jerry
2008-04-30 20:36 ` Jerry
2008-04-30 21:53   ` Adam Beneschan
2008-05-01  1:05     ` Jerry
2014-05-22  7:27   ` jan.de.kruyf
2014-05-22  8:09     ` Dmitry A. Kazakov
2014-05-22  9:24       ` Simon Wright
2014-05-22  9:48         ` Dmitry A. Kazakov
2014-05-22 15:28           ` Adam Beneschan
2014-05-22 16:31             ` Dmitry A. Kazakov
2014-05-22 23:33               ` Adam Beneschan
2014-05-23  7:38                 ` Dmitry A. Kazakov
2014-05-23 21:39                 ` Randy Brukardt
2014-05-27  8:35                   ` Dmitry A. Kazakov
2014-05-27 12:35                   ` Maurizio Tomasi
2014-05-27 15:53                     ` Adam Beneschan
2014-05-27 22:35                       ` Randy Brukardt
2014-05-27 22:59                         ` Jeffrey Carter
2014-05-28  7:32                         ` Dmitry A. Kazakov
2014-05-28  8:40                       ` Maurizio Tomasi
2008-05-05 18:23 ` Martin Krischik
2008-05-05 20:49   ` Adam Beneschan
2008-05-06 18:09     ` Jerry
2008-05-06 18:45       ` Wiljan Derks
2008-05-06 22:18         ` Adam Beneschan
2008-05-07 22:56           ` Randy Brukardt
2008-05-07 22:56           ` Randy Brukardt
2008-05-07 23:20             ` Adam Beneschan
2008-05-09  7:24             ` Stephen Leake
2008-05-10 17:00   ` anon
2008-05-11 22:00     ` Keith Thompson
2008-05-12  2:01       ` anon
2008-05-09 19:49 ` anon
2008-05-10  2:36   ` Jerry
2008-05-10  3:53     ` anon
2008-05-10  6:24       ` christoph.grein
2008-05-10  8:05     ` Georg Bauhaus

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox