[m-rev.] for review: mercury implementation of string__format

Peter Ross pro at missioncriticalit.com
Fri Nov 22 23:20:04 AEDT 2002


On Fri, Nov 22, 2002 at 10:29:14PM +1100, Fergus Henderson wrote:
> On 22-Nov-2002, Peter Ross <pro at missioncriticalit.com> wrote:
> > fjh wrote:
> > > On 21-Nov-2002, Peter Ross <pro at missioncriticalit.com> wrote:
> > > > +:- pragma promise_pure(is_nan/1).
> > > > +:- pragma foreign_proc(c, is_nan(Flt::in),
> > > > + [will_not_call_mercury, thread_safe], "
> > > > +#if MR_USE_SINGLE_PREC_FLOAT
> > > > + SUCCESS_INDICATOR = isnanf(Flt);
> > > > +#else
> > > > + SUCCESS_INDICATOR = isnan(Flt);
> > > > +#endif
> > >
> > > The use of isnan() and isnanf() need to be protected by
> > > conditional compilation, since not all systems support them.
> > >
> > > Likewise for isinf() and isinff().
> >
> > I plan to to call #error if is* aren't defined, but add a comment that it
> > may be safe to just return false if the system doesn't support IEEE
> > arthimetic.  Is this acceptable to everyone?
> 
> I think a better fall-back is to use `(Flt != Flt)' for is_nan and
> `(Flt == Flt * 2.0 && Flt != 0.0)' for is_inf.  Those should work on
> any system where the C compiler supports IEEE float properly, even if
> the C library doesn't have isinf() or isnan().  If the system doesn't
> support IEEE arithmetic this should still do something reasonable.
> If the C compiler doesn't support IEEE arithmetic properly then it may
> incorrectly optimize these tests to just return false but I think
> that is likely to be more useful than #error.
> 
> Also, for the MR_USE_SINGLE_PREC_FLOAT case, you should fall back to
> calling isnan() and isinf() if isnanf() and isinff() are not defined.
> 

diff -u library/float.m library/float.m
--- library/float.m
+++ library/float.m
@@ -448,20 +448,12 @@
 :- pragma promise_pure(is_nan/1).
 :- pragma foreign_proc(c, is_nan(Flt::in),
 		[will_not_call_mercury, thread_safe], "
-#if MR_USE_SINGLE_PREC_FLOAT
-  #ifdef MR_HAVE_ISNANF
+#if defined(MR_USE_SINGLE_PREC_FLOAT) && defined(MR_HAVE_ISNANF)
 	SUCCESS_INDICATOR = isnanf(Flt);
-  #else
-    #error ""isnanf not available. Delete this line if not IEEE fp system.""
-	SUCCESS_INDICATOR = MR_FALSE;
-  #endif
+#elif defined(MR_HAVE_ISNAN)
+	SUCCESS_INDICATOR = isnan((double) Flt);
 #else
-  #ifdef MR_HAVE_ISNAN
-	SUCCESS_INDICATOR = isnan(Flt);
-  #else
-    #error ""isnan not available. Delete this line if not IEEE fp system.""
-	SUCCESS_INDICATOR = MR_FALSE;
-  #endif
+	SUCCESS_INDICATOR = (Flt != Flt);
 #endif
 ").
 :- pragma foreign_proc(il, is_nan(Flt::in),
@@ -478,20 +470,12 @@
 :- pragma promise_pure(is_inf/1).
 :- pragma foreign_proc(c, is_inf(Flt::in),
 		[will_not_call_mercury, thread_safe], "
-#if MR_USE_SINGLE_PREC_FLOAT
-  #ifdef MR_HAVE_ISINFF
+#if defined(MR_USE_SINGLE_PREC_FLOAT) && defined(MR_HAVE_ISINFF)
 	SUCCESS_INDICATOR = isinff(Flt);
-  #else
-    #error ""isinff not available. Delete this line if not IEEE fp system.""
-	SUCCESS_INDICATOR = MR_FALSE;
-  #endif
+#elif defined(MR_HAVE_ISINF)
+	SUCCESS_INDICATOR = isinf((double) Flt);
 #else
-  #ifdef MR_HAVE_ISINF
-	SUCCESS_INDICATOR = isinf(Flt);
-  #else
-    #error ""isinf not available. Delete this line if not IEEE fp system.""
-	SUCCESS_INDICATOR = MR_FALSE;
-  #endif
+	SUCCESS_INDICATOR = (Flt == Flt * 2.0 && Flt != 0.0);
 #endif
 ").
 :- pragma foreign_proc(il, is_inf(Flt::in),
--------------------------------------------------------------------------
mercury-reviews mailing list
post:  mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------



More information about the reviews mailing list