[gfortran] I/O of large integer and real kinds, round 2
Steve Kargl
sgk@troutmask.apl.washington.edu
Tue Jun 21 23:16:00 GMT 2005
On Thu, Jun 09, 2005 at 12:50:04AM +0200, FX Coudert wrote:
> >Built, tested and regtested on:
> > - i686-linux, which has real(10)
> > - i386-freebsd
> > - sparc-solaris, which has real(16)
> > - x86_64-linux, which has real(10) and integer(16)
> > - alpha-linux, which has integer(16)
> >
> >OK for mainline? (and should it be backported to 4.0, too?)
>
> Tobias told me I sent a barely readable patch with no context around my
> changes. Sorry for the inconvenience (and then, how many times a week do
> I say "sorry" on this list? it's high time to upgrade my brain).
>
FX, I think that this patch is ok with the exception of
your implementation of log10l(). I don't understand how
your regression tests where able to pass when there is
no provision for small numbers. In particular, tiny(1._10)
is something like 3e-4391. The current implementation of
of log10l() will call log10() with 3e-4391. On FreeBSD,
this isn't a Good Thing.
I've attached an alternative implementation of log10l()
that permits amd64-*-freebsd to pass the regression tests.
Note, to accommondate the corner case of huge(1._10) I
had to reduce the integers proposed by rth by 1. I likewise
increased the integers for tiny(1._10) by 1.
--
steve
-------------- next part --------------
Index: c99_functions.c
===================================================================
RCS file: /cvs/gcc/gcc/libgfortran/intrinsics/c99_functions.c,v
retrieving revision 1.12
diff -c -p -r1.12 c99_functions.c
*** c99_functions.c 15 Jun 2005 08:40:35 -0000 1.12
--- c99_functions.c 21 Jun 2005 23:06:34 -0000
*************** roundf(float x)
*** 371,373 ****
--- 371,411 ----
}
}
#endif
+
+ #ifndef HAVE_LOG10L
+ /* log10 function for long double variables. The version provided here
+ reduces the argument until it fits into a double, then use log10. */
+ long double
+ log10l(long double x)
+ {
+ #if LDBL_MAX_EXP > DBL_MAX_EXP
+ if (x > DBL_MAX)
+ {
+ double val;
+ int p2_result = 0;
+ if (x > 0x1p16383L) { p2_result += 16383; x /= 0x1p16383L; }
+ if (x > 0x1p8191L) { p2_result += 8191; x /= 0x1p8191L; }
+ if (x > 0x1p4095L) { p2_result += 4095; x /= 0x1p4095L; }
+ if (x > 0x1p2047L) { p2_result += 2047; x /= 0x1p2047L; }
+ if (x > 0x1p1023L) { p2_result += 1023; x /= 0x1p1023L; }
+ val = log10 ((double) x);
+ return (val + p2_result * .30102999566398119521373889472449302L);
+ }
+ #endif
+ #if LDBL_MIN_EXP < DBL_MIN_EXP
+ if (x < DBL_MIN)
+ {
+ double val;
+ int p2_result = 0;
+ if (x < 0x1p-16380L) { p2_result += 16380; x /= 0x1p-16380L; }
+ if (x < 0x1p-8189L) { p2_result += 8189; x /= 0x1p-8189L; }
+ if (x < 0x1p-4093L) { p2_result += 4093; x /= 0x1p-4093L; }
+ if (x < 0x1p-2045L) { p2_result += 2045; x /= 0x1p-2045L; }
+ if (x < 0x1p-1021L) { p2_result += 1021; x /= 0x1p-1021L; }
+ val = abs(log10 ((double) x));
+ return (val + p2_result * .30102999566398119521373889472449302L);
+ }
+ #endif
+ return log10 (x);
+ }
+ #endif
More information about the Fortran
mailing list