--- Begin Message ---
Subject: |
Patch: `>>' can't read what `<<' produced: NaNs and Inf |
Date: |
Sat, 10 Apr 1999 05:54:02 +0100 |
Hi,
I enclose a diff against a clean egcs-1.1.2/libio/iovfscanf.c and a test
file to show the patch effect. The patch applies also cleanly to
libstdc++-2.90.4, but I have not tested it with that distribution.
Implementing the changes at this level will affect all derived classes.
I have relinked some C++ applications with the newly created lib and
they work OK.
The decision to implement the changes only at iovfscanf.c and not also
at floatconv.c, _IO_strtod(), was due to a conditional compilation at
iovfscanf.c that could imply that in some platforms the system atof()
would be used, with no warranty that it would be able to read inf/nan's.
This makes the patch a bit ugly.
The test case, teste2.cc, should produce the following output:
1. -INF +INF INF
-Infinity Infinity Infinity
2. -Inf +Inf Inf
-Infinity Infinity Infinity
3. -inf +inf inf
-Infinity Infinity Infinity
4. -infI +iNfiN iNfInity
-Infinity Infinity Infinity
5. -nan +nan nan
-NaN -NaN -NaN
6. -NaN +NaN NaN
-NaN -NaN -NaN
7. -NAN +NAN NAN
-NaN -NaN -NaN
8. -NAN(0x123123) +NaN(0x5464) nan(0x34)
-NaN -NaN -NaN
9. -121.12 NaN +3123.4 Inf 0.232
-121.12 -NaN 3123.4 Infinity 0.232
If you have any problem with the patch, please contact me or
<address@hidden>, the real code writer.
Hopping that this will be accepted,
Joao
--
Joao Cardoso, INESC | e-mail: address@hidden
R. Jose Falcao 110 | tel: + 351 2 2094345
4050 Porto, Portugal | fax: + 351 2 2008487
#include <strstream.h>
#include <ieeefp.h>
main(){
double x=1./0., y=0./0.;
double a=0.1, b=0.1, d=0.1, e=0.1, f=0.1, g=0.1, h=0.1, j=0.1;
char c, buf[100];
ostrstream os(buf,100);
istrstream is(buf,100);
os << "-INF\t" << "+INF\t" << "INF" << '\0';
is >> a >> c >> b >> c >> d >> c;
if (finite(a) || finite(b) || finite(d))
cout << "1- Error\n";
cout << "1. " << buf << "\n " << a << "\t" << b << "\t" << d << '\n';
os.seekp(ios::beg);
is.seekg(0L,ios::beg);
os << "-Inf\t" << "+Inf\t" << "Inf" << '\0';
is >> a >> c >> b >> c >> d >> c;
if (finite(a) || finite(b) || finite(d))
cout << "2- Error\n";
cout << "2. " << buf << "\n " << a << "\t" << b << "\t" << d << '\n';
os.seekp(ios::beg);
is.seekg(0L,ios::beg);
os << "-inf\t" << "+inf\t" << "inf" << '\0';
is >> a >> c >> b >> c >> d >> c;
if (finite(a) || finite(b) || finite(d))
cout << "3- Error\n";
cout << "3. " << buf << "\n " << a << "\t" << b << "\t" << d << '\n';
os.seekp(ios::beg);
is.seekg(0L,ios::beg);
os << "-infI\t" << "+iNfiN\t" << "iNfInity" << '\0';
is >> a >> c >> b >> c >> d >> c;
if (finite(a) || finite(b) || finite(d))
cout << "4- Error\n";
cout << "4. " << buf << "\n " << a << "\t" << b << "\t" << d << '\n';
os.seekp(ios::beg);
is.seekg(0L,ios::beg);
os << "-nan\t" << "+nan\t" << "nan" << '\0';
is >> a >> c >> b >> c >> d >> c;
if (!isnand(a) || !isnand(b) || !isnand(d))
cout << "5- Error\n";
cout << "5. " << buf << "\n " << a << "\t" << b << "\t" << d << '\n';
os.seekp(ios::beg);
is.seekg(0L,ios::beg);
os << "-NaN\t" << "+NaN\t" << "NaN" << '\0';
is >> a >> c >> b >> c >> d >> c;
if (!isnand(a) || !isnand(b) || !isnand(d))
cout << "6- Error\n";
cout << "6. " << buf << "\n " << a << "\t" << b << "\t" << d << '\n';
os.seekp(ios::beg);
is.seekg(0L,ios::beg);
os << "-NAN\t" << "+NAN\t" << "NAN" << '\0';
is >> a >> c >> b >> c >> d >> c;
if (!isnand(a) || !isnand(b) || !isnand(d))
cout << "7- Error\n";
cout << "7. " << buf << "\n " << a << "\t" << b << "\t" << d << '\n';
os.seekp(ios::beg);
is.seekg(0L,ios::beg);
os << "-NAN(0x123123)\t" << "+NaN(0x5464)\t" << "nan(0x34)" << '\0';
is >> a >> c >> b >> c >> d >> c;
if (!isnand(a) || !isnand(b) || !isnand(d))
cout << "8- Error\n";
cout << "8. " << buf << "\n " << a << "\t" << b << "\t" << d << '\n';
os.seekp(ios::beg);
is.seekg(0L,ios::beg);
os << "-121.12\t" << "NaN\t" << "+3123.4\t" << "Inf\t" << "0.232" << '\0';
is >> a >> c >> b >> c >> d >> c >> e >> c >> f;
if (a != -121.12 || !isnand(b) || d != 3123.4 || finite(e) || f !=
0.232)
cout << "9- Error\n";
cout << "9. " << buf << "\n " << a << "\t" << b << "\t" << d << "\t"
<< e << "\t" << f <<'\n';
}
*** iovfscanf.c.org Sat Apr 10 04:10:34 1999
--- iovfscanf.c Sat Apr 10 05:03:34 1999
***************
*** 81,86 ****
--- 81,88 ----
* SIGNOK, NDIGITS, DPTOK, and EXPOK are for floating point;
* SIGNOK, NDIGITS, PFXOK, and NZDIGITS are for integral.
*/
+ #define NNAN 0x02
+ #define NINF 0x04
#define SIGNOK 0x40 /* +/- is (still) legal */
#define NDIGITS 0x80 /* no digits detected */
***************
*** 627,632 ****
--- 629,641 ----
goto fok;
}
break;
+ case 'n': case 'N': case 'i': case 'I':
+ flags|=NNAN;
+ case 'f': case 't': case 'y': case 'a':
+ case 'F': case 'T': case 'Y': case 'A':
+ case 'x': case 'X': case '(': case ')':
+ if(flags&NNAN)
+ goto fok;
}
break;
fok:
***************
*** 637,642 ****
--- 646,659 ----
break; /* EOF */
}
}
+
+ if (flags & NNAN) {
+ flags|=NDIGITS|EXPOK;
+ if((flags & SIGNOK)==0)
+ if ((*buf!='+')&&(*buf!='-'))
+ flags|=SIGNOK;
+ }
+
/*
* If no digits, might be missing exponent digits
* (just give back the exponent) or might be missing
***************
*** 644,654 ****
*/
if (flags & NDIGITS) {
if (flags & EXPOK) {
! /* no digits at all */
! while (p > buf)
_IO_ungetc (*(u_char *)--p, fp);
! goto match_failure;
! }
/* just a bad exponent (e and maybe sign) */
c = *(u_char *)--p;
if (c != 'e' && c != 'E') {
--- 661,706 ----
*/
if (flags & NDIGITS) {
if (flags & EXPOK) {
! int sign;
! double res;
! char *s;
!
! sign=1;
! s=buf;
! flags&=~(NINF|NNAN);
! if((flags & SIGNOK)==0)
! sign= (*s++=='-')? -1: 1;
!
! if(*s=='I'||*s=='i') {
! ++s;
! if(*s=='N'||*s=='n') {
! ++s;
! if(*s=='F'||*s=='f')
! flags|=NINF;
! }
! }
! else if(*s=='N'||*s=='n') {
! ++s;
! if(*s=='A'||*s=='a') {
! ++s;
! if(*s=='N'||*s=='n')
! flags|=NNAN;
! }
! }
! if (flags&(NINF|NNAN)) {
! nassigned++;
! res= (double)sign*(((flags &
NINF))?1.0/0.:0./0.);
! if (flags & LONG)
! *va_arg(ap, double *) =
res;
! else
! *va_arg(ap, float *) =
res;
! break;
! }
! /* no digits at all */
! while (p > buf)
_IO_ungetc (*(u_char *)--p, fp);
! goto match_failure;
! }
/* just a bad exponent (e and maybe sign) */
c = *(u_char *)--p;
if (c != 'e' && c != 'E') {
--- End Message ---