No subject

Fred Tydeman sun!uunet.UU.NET!ibmsupt!ibmpa!tydeman
Thu Aug 2 13:59:48 PDT 1990


Subject:  Code to test support of infinity and Not-a-Number as strings
 
The  following is  a program  to  test an  implementation's support  for
infinity  and  Not-a-Number  (NaN)  as  strings  for  input  and  output
conversions.  It is  based upon IBM's proposal to the  NCEG (Numerical C
Extensions  Group).     We   believe  that   a  short   standard  string
representation for infinity  is needed, namely, INF.  We  believe that a
short standard  string representation  for quiet  NaN is  needed, namely
NaNQ.   We believe  that a  short standard  string representation  for a
signaling NaN is needed, namely, NaNS.  Our reading of IEEE-854 says the
string NaN should be recognized as  a signaling NaN.  The representation
in the case of the general NaN, one where the significand is an (almost)
arbitrary value,  is to be determined.   Some implementations  have used
NaN() as a starting point for an arbitrary  NaN, where the () were to be
filled in by some string of a format to be determined.
 
Output         Input                  Representing
------         -----                  ------------
INF            INF or infinity        Infinity
NaNQ           NaNQ                   Quiet Not-a-Number
NaNS           NaNS or NaN            Signaling Not-a-Number
NaN()          NaN()                  General Not-a-Number (to be done)
 
The code follows:
 
/*                          Unclassified                               */
/*                                                                     */
/*                Copyright IBM Corporation 1989, 1990                 */
/*                                                                     */
/*                       All Rights Reserved                           */
/*                                                                     */
/*  Permission to use, copy, modify, and distribute this software and  */
/*  its documentation  without fee is  hereby granted,  provided that  */
/*  the above  copyright notice  appear in all  copies and  that both  */
/*  that  copyright  notice  and this  permission  notice  appear  in  */
/*  supporting documentation, and that the name of IBM not be used in  */
/*  advertising  or  publicity  pertaining  to  distribution  of  the  */
/*  software without  specific, written prior  permission.   The user  */
/*  understands and agrees that this program and any derivative works  */
/*  are to  be used solely  for experimental uses  and are not  to be  */
/*  sold,  licensed  or  distributed  for a  fee  or  profit,  or  be  */
/*  commercially exploited in any manner.                              */
/*                                                                     */
/*  IBM  DISCLAIMS  ALL  WARRANTIES WITH  REGARD  TO  THIS  SOFTWARE,  */
/*  INCLUDING ALL  IMPLIED WARRANTIES OF MERCHANTABILITY  AND FITNESS  */
/*  FOR A PARTICULAR  USE.  IN NO  EVENT SHALL IBM BE  LIABLE FOR ANY  */
/*  SPECIAL,  INDIRECT  OR  CONSEQUENTIAL   DAMAGES  OR  ANY  DAMAGES  */
/*  WHATSOEVER RESULTING FROM  LOSS OF USE, DATA  OR PROFITS, WHETHER  */
/*  IN AN  ACTION OF CONTRACT,  NEGLIGENCE OR OTHER  TORTIOUS ACTION,  */
/*  ARISING OUT  OF OR IN CONNECTION  WITH THE USE OR  PERFORMANCE OF  */
/*  THIS SOFTWARE.                                                     */
/*                                                                     */
/*=====================================================================*/
/*                                                                     */
/* Purpose of this test:                                               */
/*                                                                     */
/*  To test your implementation's support for infinity and NaN (Not a  */
/*  Number)  from IEEE-854  Floating-Point Standard  in  ANSI "C"  as  */
/*  extended by a  proposal to the Numerical "C"  Extensions Group in  */
/*  the  area  of  scanf,  printf,  strtod,   atof,  and  gcvt.    In  */
/*  particular, the string "INF" for  infinity, "NaNQ" for quiet NaN,  */
/*  and "NaNS" for signaling NaN.                                      */
/*                                                                     */
/* Assumptions:                                                        */
/*                                                                     */
/*  Your system (hardware and software)  support IEEE-754 or IEEE-854  */
/*  in binary (not decimal) mode.   Your system supports the sign bit  */
/*  on NaNs.   Your  system is (close  to) ANSI  "C" compliant.   C's  */
/*  float is mapped to  a 32-bit IEEE single which is  a 4 byte item.  */
/*  C's double is mapped  to a 64-bit IEEE double which  is an 8 byte  */
/*  item.  The default locale ("C") recognizes the NCEG strings (just  */
/*  doing  IEEE  math  with inexact  and/or  NaN  exceptions,  causes  */
/*  undefined behavior (ANSI  "C", section 3.3, fifth  paragraph), so  */
/*  once  you have  undefined behavior  in your  program, having  the  */
/*  default locale recognize the NCEG strings may be allowed).         */
/*                                                                     */
/* What you need to do to run this:                                    */
/*                                                                     */
/* 1)  Modify the #defines for your system.   They are related to how  */
/*     much  output you  want (ECHO_GOOD),  the  internal values  for  */
/*     Signaling and Quiet NaN (..NAN.),  your compiler's support for  */
/*     'const' (CONST), 'volatile' (VOLATILE), '(void *)' (VOID_STAR)  */
/*     and if you wish to test gcvt  (CVT), which is not part of ANSI  */
/*     "C".    These  defines  are   all  located  just  after  these  */
/*     instructions and before  the meaning of the error  codes.  The  */
/*     rest of the defines and code should not need to be modified.    */
/*                                                                     */
/* 2)  Compile the code:  cc naninfpd.c                                */
/*                                                                     */
/* 3)  Run the code:  a.out                                            */
/*                                                                     */
/* 4)  Check the output.   If everything is  working correctly, then   */
/*     each test case  will output a line  that starts with OK.   If   */
/*     something  is wrong,  it will  attempt  to tell  you what  is   */
/*     wrong.  All error messages have a two digit number so you can   */
/*     find the exact line in error, in the code, easier.              */
/*                                                                     */
/*=====================================================================*/
/* This  should  be set  up  to  compile  and  run on  your  various   */
/* platforms by changing the next several #defines.                    */
/*                                                                     */
/*---------------------------------------------------------------------*/
/* To control 'OK:' messages, choose one of the following two lines:   */
 
#undef  ECHO_GOOD       /* Silence if all is OK.                       */
#define ECHO_GOOD 1     /* Let user know tests passed.                 */
 
/*---------------------------------------------------------------------*/
/*      Define machine dependent constants: IEEE binary format:        */
/*      s = single precision, d = double precision                     */
/*      p = positive,         m = minus                                */
 
#define dpNANS "0x7ff7ffffffffffff"
#define dmNANS "0xfff7ffffffffffff"
#define spNANS "0x7fbfffff"
#define smNANS "0xffbfffff"
 
#define dpNANQ "0x7fffffffffffffff"
#define dmNANQ "0xffffffffffffffff"
#define spNANQ "0x7fffffff"
#define smNANQ "0xffffffff"
 
#if 0   /* another example of IEEE-754 values */
#define dpNANS "0x7ff5555555555555"
#define dmNANS "0xfff5555555555555"
#define spNANS "0x7f855555"
#define smNANS "0xff855555"
 
#define dpNANQ "0x7ff8000000000000"
#define dmNANQ "0xfff8000000000000"
#define spNANQ "0x7fc00000"
#define smNANQ "0xffc00000"
#endif
 
/*---------------------------------------------------------------------*/
/*      Define compiler dependent constants:                           */
 
#define CONST    const       /* or blanks if not full ANSI "C" */
#define VOLATILE volatile    /* or blanks if not full ANSI "C" */
#define VOID_STAR (void *)   /* or blanks if not full ANSI "C" */
 
/*---------------------------------------------------------------------*/
/* To control testing 'gcvt', choose one of the following two lines:   */
 
#undef  CVT             /* gcvt not supported.                         */
#define CVT       1     /* If want to test gcvt routines.              */
 
/*---------------------------------------------------------------------*/
/* The rest of the code should not need to be changed; just above defs */
 
/*=====================================================================*/
/*                                                                     */
/* Meaning of the error codes:                                         */
/*                                                                     */
/* 00 The internal representation  of a NaNQ as returned  by sscanf is */
/*    different than the result of 0.0  / 0.0 (ignoring the sign bit). */
/*    This assumes that there is one preferred internal representation */
/*    of quiet NaNs, that is 0.0 / 0.0 is the same as inf / inf is the */
/*    same as inf - inf, and that sscanf should return that number.    */
/*                                                                     */
/* 01 sprintf  of  a  float  value (promoted  to  double)  via  "%.0e" */
/*    produced a  string different than what  was expected.   What was */
/*    produced and  what was  expected are  listed.   The most  common */
/*    error  is  the   value  is  converted  to   a  different  string */
/*    representation than the suggested one for NaN and/or infinity.   */
/* 02 sscanf of  a string via "%e"  into a float produced  an internal */
/*    representation  different that  what was  expected.   The  input */
/*    string, what was produced and what was expected are listed.      */
/* 03 sscanf of a string via "%e" into  a float failed to process that */
/*    string.  The  string is listed.   The most common cause  is your */
/*    system does not support the suggested string representations for */
/*    NaN and/or infinity.                                             */
/*                                                                     */
/* 04 sprintf  of  a  float  value (promoted  to  double)  via  "%.0E" */
/*    produced a  string different than what  was expected.   What was */
/*    produced and  what was  expected are  listed.   The most  common */
/*    error  is  the   value  is  converted  to   a  different  string */
/*    representation than the suggested one for NaN and/or infinity.   */
/* 05 sscanf of  a string via "%E"  into a float produced  an internal */
/*    representation  different that  what was  expected.   The  input */
/*    string, what was produced and what was expected are listed.  The */
/*    most common  error is  the value  is converted  and stored  as a */
/*    double, rather, than as a float.                                 */
/* 06 sscanf of a string via "%E" into  a float failed to process that */
/*    string.  The  most common cause is your system  does not support */
/*    the suggested string representations for NaN and/or infinity.    */
/*                                                                     */
/* 07 sprintf  of  a  float  value (promoted  to  double)  via  "%.0f" */
/*    produced a  string different than what  was expected.   What was */
/*    produced and  what was  expected are  listed.   The most  common */
/*    error  is  the   value  is  converted  to   a  different  string */
/*    representation than the suggested one for NaN and/or infinity.   */
/* 08 sscanf of  a string via "%f"  into a float produced  an internal */
/*    representation  different that  what was  expected.   The  input */
/*    string, what was produced and what was expected are listed.      */
/* 09 sscanf of a string via "%f" into  a float failed to process that */
/*    string.  The  most common cause is your system  does not support */
/*    the suggested string representations for NaN and/or infinity.    */
/*                                                                     */
/* 10 sprintf  of  a  float  value (promoted  to  double)  via  "%.0g" */
/*    produced a  string different than what  was expected.   What was */
/*    produced and  what was  expected are  listed.   The most  common */
/*    error  is  the   value  is  converted  to   a  different  string */
/*    representation than the suggested one for NaN and/or infinity.   */
/* 11 sscanf of  a string via "%g"  into a float produced  an internal */
/*    representation  different that  what was  expected.   The  input */
/*    string, what was produced and what was expected are listed.      */
/* 12 sscanf of a string via "%g" into  a float failed to process that */
/*    string.  The  most common cause is your system  does not support */
/*    the suggested string representations for NaN and/or infinity.    */
/*                                                                     */
/* 13 sprintf  of  a  float  value (promoted  to  double)  via  "%.0G" */
/*    produced a  string different than what  was expected.   What was */
/*    produced and  what was  expected are  listed.   The most  common */
/*    error  is  the   value  is  converted  to   a  different  string */
/*    representation than the suggested one for NaN and/or infinity.   */
/* 14 sscanf of  a string via "%G"  into a float produced  an internal */
/*    representation  different that  what was  expected.   The  input */
/*    string, what was produced and what was expected are listed.  The */
/*    most common  error is  the value  is converted  and stored  as a */
/*    double, rather, than as a float.                                 */
/* 15 sscanf of a string via "%G" into  a float failed to process that */
/*    string.  The  most common cause is your system  does not support */
/*    the suggested string representations for NaN and/or infinity.    */
/*                                                                     */
/* 16 sprintf of a double value via "%.0e" produced a string different */
/*    than what was expected.  What was produced and what was expected */
/*    are listed.  The most common error  is the value is converted to */
/*    a different string representation than the suggested one for NaN */
/*    and/or infinity.                                                 */
/* 17 sscanf of a string via "%le"  into a double produced an internal */
/*    representation  different that  what was  expected.   The  input */
/*    string, what was produced and what was expected are listed.      */
/* 18 sscanf of  a string via  "%le" into  a double failed  to process */
/*    that string.   The  most common  cause is  your system  does not */
/*    support  the suggested  string  representations  for NaN  and/or */
/*    infinity.                                                        */
/*                                                                     */
/* 19 sprintf of a double value via "%.0E" produced a string different */
/*    than what was expected.  What was produced and what was expected */
/*    are listed.  The most common error  is the value is converted to */
/*    a different string representation than the suggested one for NaN */
/*    and/or infinity.                                                 */
/* 20 sscanf of a string via "%lE"  into a double produced an internal */
/*    representation  different that  what was  expected.   The  input */
/*    string, what was produced and what was expected are listed.      */
/* 21 sscanf of  a string via  "%lE" into  a double failed  to process */
/*    that string.   The  most common  cause is  your system  does not */
/*    support  the suggested  string  representations  for NaN  and/or */
/*    infinity.                                                        */
/*                                                                     */
/* 22 sprintf of a double value via "%.0f" produced a string different */
/*    than what was expected.  What was produced and what was expected */
/*    are listed.  The most common error  is the value is converted to */
/*    a different string representation than the suggested one for NaN */
/*    and/or infinity.                                                 */
/* 23 sscanf of a string via "%lf"  into a double produced an internal */
/*    representation  different that  what was  expected.   The  input */
/*    string, what was produced and what was expected are listed.      */
/* 24 sscanf of  a string via  "%lf" into  a double failed  to process */
/*    that string.   The  most common  cause is  your system  does not */
/*    support  the suggested  string  representations  for NaN  and/or */
/*    infinity.                                                        */
/*                                                                     */
/* 25 sprintf of a double value via "%.0g" produced a string different */
/*    than what was expected.  What was produced and what was expected */
/*    are listed.  The most common error  is the value is converted to */
/*    a different string representation than the suggested one for NaN */
/*    and/or infinity.                                                 */
/* 26 sscanf of a string via "%lg"  into a double produced an internal */
/*    representation  different that  what was  expected.   The  input */
/*    string, what was produced and what was expected are listed.      */
/* 27 sscanf of  a string via  "%lg" into  a double failed  to process */
/*    that string.   The  most common  cause is  your system  does not */
/*    support  the suggested  string  representations  for NaN  and/or */
/*    infinity.                                                        */
/*                                                                     */
/* 28 sprintf of a double value via "%.0G" produced a string different */
/*    than what was expected.  What was produced and what was expected */
/*    are listed.  The most common error  is the value is converted to */
/*    a different string representation than the suggested one for NaN */
/*    and/or infinity.                                                 */
/* 29 sscanf of a string via "%lG"  into a double produced an internal */
/*    representation  different that  what was  expected.   The  input */
/*    string, what was produced and what was expected are listed.      */
/* 30 sscanf of  a string via  "%lG" into  a double failed  to process */
/*    that string.   The  most common  cause is  your system  does not */
/*    support  the suggested  string  representations  for NaN  and/or */
/*    infinity.                                                        */
/*                                                                     */
/* 31 atof  of   a  string   into  a   double  produced   an  internal */
/*    representation  different that  what was  expected.   The  input */
/*    string, what was produced and what was expected are listed.      */
/* 32 atof of  a string into a  double failed to process  that string. */
/*    The  most common  cause  is your  system  does  not support  the */
/*    suggested string representations for NaN and/or infinity.        */
/*                                                                     */
/* 33 strtod of a string returned the pointer to the final string with */
/*    the wrong value.  The character that pointer is pointing to, the */
/*    character that  was expected,  and the string  are listed.   The */
/*    characters are printed in hex, since  a nul (00) is the expected */
/*    character in many  cases.  The most common cause  is your system */
/*    does not  support the suggested  string representations  for NaN */
/*    and/or infinity.                                                 */
/* 34 strtod  of  a   string  into  a  double   produced  an  internal */
/*    representation  different that  what was  expected.   The  input */
/*    string, what was produced and what was expected are listed.      */
/* 35 strtod of a string into a  double failed to process that string. */
/*    The  most common  cause  is your  system  does  not support  the */
/*    suggested string representations for NaN and/or infinity.        */
/*                                                                     */
/* 36 gcvt of a double value produced a string different than what was */
/*    expected.  What was produced, what  was expected, and the string */
/*    string "converted" by strtod to a double to then be converted by */
/*    gcvt  are  listed.   The  most  common  error  is the  value  is */
/*    converted  to   a  different  string  representation   than  the */
/*    suggested one for  NaN and/or infinity.  The  other common error */
/*    is the preceding strtod produced the wrong value internally,  so */
/*    gcvt is  given the wrong value  to convert (make sure  strtod is */
/*    correct first).                                                  */
/*                                                                     */
/* 45 This program was unable to  determine how floating-point numbers */
/*    are stored  internally.  It tries to do  the two common  ways of */
/*    big-endian   (most  significant   byte  at   low  address)   and */
/*    little-endian (least significant byte at  low address).  Because */
/*    of this, the  results of the other  tests are suspect.   This is */
/*    caused by not meeting the assumptions this program makes.        */
/*                                                                     */
/* 50 The internal representation  of -NaNQ is the same as  +NaNQ as a */
/*    float.  This can happen because the floating point unit does not */
/*    support  signed  NaNs  (which is  allowed  by  the  IEEE-754/854 */
/*    standards).  If this  is the case, then many of  the other tests */
/*    will fail.                                                       */
/* 51 The internal representation  of -NaNQ is the same as  +NaNQ as a */
/*    double.   This can happen because  the floating point  unit does */
/*    not support  signed NaNs (which  is allowed by  the IEEE-754/854 */
/*    standards).  If this  is the case, then many of  the other tests */
/*    will fail.                                                       */
/*                                                                     */
/*=====================================================================*/
/* This program has been run on several systems (hardware/software     */
/* combinations) from various vendors.  The following problems have    */
/* been found:                                                         */
/*   Segmentation fault on first sscanf                                */
/*   sscanf("INF","%E",&float) done as double                          */
/*   sscanf("INF","%G",&float) done as double                          */
/*   sprintf(out,"%.0f",-INF)  outputs INF (drops sign)                */
/*   gcvt(Inf) outputs I.NF; should be INF                             */
/*   gcvt(Inf) outputs 0.INF; should be INF                            */
/*   atof("INF") is 0; should be infinity                              */
/*   strtod("INF") is 0; should be infinity                            */
/*   strtod("INFINITE",&ptr) returns bad pointer location              */
/*   atof("-INF") is 1.e-314; should be -infinity                      */
/*   strtod("-INF") is 1.e-314; should be -infinity                    */
/*   sscanf("1e4294967296") is 1, not infinity                         */
/*   strtod("1e4294967296") is 1, not infinity                         */
/*   atof("1e4294967296") is 1, not infinity                           */
/*   Signaling NaNs not handled, in or out                             */
/*   Signed NaNs not handled, ie -NaN == NaN                           */
/*   0./0. internally is not same as sscanf(NaNQ)                      */
/*   sprintf(out,"%.0f",-NaNS) outputs NaNS (drops sign)               */
/*   sprintf(out,"%.0e",-NAN())outputs NAN() (drops sign)              */
/*   sprintf(out,"%.0f",-NAN())outputs NAN() (drops sign)              */
/*   sprintf(out,"%.0g",-NAN())outputs NAN() (drops sign)              */
/*   sprintf(out,"%.0e",NaNS)  outputs NaNS (float to double convert)  */
/*   sprintf(out,"%.0f",NaNS)  outputs NaNS (float to double convert)  */
/*   sprintf(out,"%.0g",NaNS)  outputs NaNS (float to double convert)  */
/*   strtod("NaN",&ptr) returns bad pointer location                   */
/*   sprintf(out,"%.0g",1)     outputs 0.e+00                          */
/*   sprintf(out,"%.0G",1)     outputs 0.E+00                          */
/*   sscanf("1/0","%E",&float) done as double                          */
/*   sscanf("1/0","%G",&float) done as double                          */
/*   gcvt(1) outputs 1.000000000000, not 1                             */
/*   gcvt(-1) outputs -1.000000000000, not -1                          */
/*   gcvt(0) outputs 0.000000000000, not 0                             */
/*   gcvt(-0) outputs -0.000000000000, not -0                          */
/*   sprintf(out,"%.0f",-0) output 0; should be -0                     */
/*   sprintf(out,"%.0g",-0) output 0; should be -0                     */
/*   sprintf(out,"%.0G",-0) output 0; should be -0                     */
/*   atof("-0") is 1.e-314; should be -0                               */
/*   compiler not support \ as last character of line                  */
/*=====================================================================*/
 
#define dpZERO  "0x0000000000000000"
#define dmZERO  "0x8000000000000000"
#define spZERO  "0x00000000"
#define smZERO  "0x80000000"
 
#define dpONE  "0x3ff0000000000000"
#define dmONE  "0xbff0000000000000"
#define spONE  "0x3f800000"
#define smONE  "0xbf800000"
 
#define dpINF  "0x7ff0000000000000"
#define dmINF  "0xfff0000000000000"
#define spINF  "0x7f800000"
#define smINF  "0xff800000"
 
#define PI      3.1415926535            /* "random" number */
#define Nul    '\0'
 
/* This set of defines determine how data is stored (big/little endian)*/
#define LITTLE_ENDIAN   1234            /* least-significant byte first
                                         * (80x86, vax)                */
#define BIG_ENDIAN      4321            /* most-significant byte first
                                         * (680x0, IBM S/370, net)     */
 
/*---------------------------------------------------------------------*/
/* These next strings are the reason for this test.  They are the      */
/* suggested strings for infinity, Signaling NaN, and Quiet NaN        */
/* to be processed by scanf, printf, strtod, ... functions.            */
/*---------------------------------------------------------------------*/
 
#define dpInf  "INF"
#define dmInf  "-INF"
#define spInf  "INF"
#define smInf  "-INF"
 
#define dpNS   "NaNS"
#define dmNS   "-NaNS"
#define spNS   "NaNQ"  /* float NaNS promoted to double NaNQ by printf*/
#define smNS   "-NaNQ" /* " */
 
#define dpNQ   "NaNQ"
#define dmNQ   "-NaNQ"
#define spNQ   "NaNQ"  /* float NaNQ promoted to double NaNQ by printf*/
#define smNQ   "-NaNQ" /* " */
 
/*=====================================================================*/
#include <stdio.h>
#include <stdlib.h>     /* atof, strtod */
#include <string.h>
/*=====================================================================*/
  int   bad;
  int   ok;
  char  s[19];          /* 0x1234567812345678\0 */
  char  ss[19];
  int   byte_order;     /* big or little endian determined at run time */
/*=====================================================================*/
char * hexer_8(s,p)     /* convert a 8 byte double into 16 hex chars */
        char * s;
CONST   double * p;
{
  char * h;
  unsigned char * q;
  int i;
  char c[3];
h = s;
q = (unsigned char *)(VOID_STAR p);
*h = '0'; h++;
*h = 'x'; h++;
if ( byte_order == LITTLE_ENDIAN ){
  for(i=7;i>=0;i--){          /* right to left for 80386 */
    sprintf(c,"%02x",(unsigned int)((unsigned char)(q[i])));
    *h = c[0]; h++;
    *h = c[1]; h++;
  };
}else{ /* byte_order == BIG_ENDIAN */
  for(i=0;i<=7;i++){           /* left to right for 68030 */
    sprintf(c,"%02x",(unsigned int)((unsigned char)(q[i])));
    *h = c[0]; h++;
    *h = c[1]; h++;
  };
};
*h = '\0';
return(s);
}/* end hexer_8 */
/*=====================================================================*/
char * hexer_4(s,p)     /* convert 4 byte float into 8 hex chars */
        char * s;
CONST   float * p;
{
  char * h;
  unsigned char * q;
  int i;
  char c[3];
h = s;
q = (unsigned char *)(VOID_STAR p);
*h = '0'; h++;
*h = 'x'; h++;
if ( byte_order == LITTLE_ENDIAN ){
  for(i=3;i>=0;i--){           /* right to left for 80386 */
    sprintf(c,"%02x",(unsigned int)((unsigned char)(q[i])));
    *h = c[0]; h++;
    *h = c[1]; h++;
  };
}else{   /* byte_order == BIG_ENDIAN */
  for(i=0;i<=3;i++){           /* left to right for 68030 */
    sprintf(c,"%02x",(unsigned int)((unsigned char)(q[i])));
    *h = c[0]; h++;
    *h = c[1]; h++;
  };
};
*h = '\0';
return(s);
}/* end hexer_4 */
/*=====================================================================*/
test( in, hexd, hexf, doutfgG, doute, doutE, outfgG, oute, outE, strch )
CONST  char * in;       /* character string to process */
CONST  char * hexd;     /* double precision, double, internal format */
CONST  char * hexf;     /* single precision, float, internal format  */
CONST  char * doutfgG;  /* double f, g, G format */
CONST  char * doute;    /* double e format */
CONST  char * doutE;    /* double E format */
CONST  char * outfgG;   /* float f, g, G format */
CONST  char * oute;     /* float e format */
CONST  char * outE;     /* float E format */
CONST  char   strch;    /* char strtod should point to */
{
  int i;
  VOLATILE float  f;
  VOLATILE double dd;
  char strout[32];
  char strhex[32];
  char * c_ptr;
 
/*----------------------------- Test floats ---------------------------*/
f = PI;
i = sscanf(in,"%e",&f);
if(i==1){
  hexer_4(strhex,&f);
  if(strcmp(hexf,strhex)==0){
  ; sprintf(strout,"%.0e",f);
  ; if(strcmp(oute,strout)==0){
  ;   ok++;
#ifdef ECHO_GOOD
  ;   printf("OK: (%s) -> (%s) as (%s)\n",in,oute,hexf);
#endif
  ; }else{
  ;   bad++;
  ;   printf("01:sprintf( %%e) produced(%s), expected(%s) for(%s)\n",
        strout,oute,in);
  ; }; /* fi */
  }else{
  ; bad++;
  ; printf("02:sscanf( %%e) produced(%s) internally, expected(%s) for(%s)\n",
        strhex,hexf,in);
  }; /* fi */
}else{
  bad++;
  printf("03:sscanf( %%e) was unable to do(%s)\n",in);
};/* fi */
 
f = PI;
i = sscanf(in,"%E",&f);
if(i==1){
  hexer_4(strhex,&f);
  if(strcmp(hexf,strhex)==0){
  ; sprintf(strout,"%.0E",f);
  ; if(strcmp(outE,strout)==0){
  ;   ok++;
#ifdef ECHO_GOOD
  ;   printf("OK: (%s) -> (%s) as (%s)\n",in,outE,hexf);
#endif
  ; }else{
  ;   bad++;
  ;   printf("04:sprintf( %%E) produced(%s), expected(%s) for(%s)\n",
        strout,outE,in);
  ; }; /* fi */
  }else{
  ; bad++;
  ; printf("05:sscanf( %%E) produced(%s) internally, expected(%s) for(%s)\n",
        strhex,hexf,in);
  }; /* fi */
}else{
  bad++;
  printf("06:sscanf( %%E) was unable to do(%s)\n",in);
};/* fi */
 
f = PI;
i = sscanf(in,"%f",&f);
if(i==1){
  hexer_4(strhex,&f);
  if(strcmp(hexf,strhex)==0){
  ; sprintf(strout,"%.0f",f);
  ; if(strcmp(outfgG,strout)==0){
  ;   ok++;
#ifdef ECHO_GOOD
  ;   printf("OK: (%s) -> (%s) as (%s)\n",in,outfgG,hexf);
#endif
  ; }else{
  ;   bad++;
  ;   printf("07:sprintf( %%f) produced(%s), expected(%s) for(%s)\n",
        strout,outfgG,in);
  ; }; /* fi */
  }else{
  ; bad++;
  ; printf("08:sscanf( %%f) produced(%s) internally, expected(%s) for(%s)\n",
        strhex,hexf,in);
  }; /* fi */
}else{
  bad++;
  printf("09:sscanf( %%f) was unable to do(%s)\n",in);
};/* fi */
 
f = PI;
i = sscanf(in,"%g",&f);
if(i==1){
  hexer_4(strhex,&f);
  if(strcmp(hexf,strhex)==0){
  ; sprintf(strout,"%.0g",f);
  ; if(strcmp(outfgG,strout)==0){
  ;   ok++;
#ifdef ECHO_GOOD
  ;   printf("OK: (%s) -> (%s) as (%s)\n",in,outfgG,hexf);
#endif
  ; }else{
  ;   bad++;
  ;   printf("10:sprintf( %%g) produced(%s), expected(%s) for(%s)\n",
        strout,outfgG,in);
  ; }; /* fi */
  }else{
  ; bad++;
  ; printf("11:sscanf( %%g) produced(%s) internally, expected(%s) for(%s)\n",
        strhex,hexf,in);
  }; /* fi */
}else{
  bad++;
  printf("12:sscanf( %%g) was unable to do(%s)\n",in);
};/* fi */
 
f = PI;
i = sscanf(in,"%G",&f);
if(i==1){
  hexer_4(strhex,&f);
  if(strcmp(hexf,strhex)==0){
  ; sprintf(strout,"%.0G",f);
  ; if(strcmp(outfgG,strout)==0){
  ;   ok++;
#ifdef ECHO_GOOD
  ;   printf("OK: (%s) -> (%s) as (%s)\n",in,outfgG,hexf);
#endif
  ; }else{
  ;   bad++;
  ;   printf("13:sprintf( %%G) produced(%s), expected(%s) for(%s)\n",
        strout,outfgG,in);
  ; }; /* fi */
  }else{
  ; bad++;
  ; printf("14:sscanf( %%G) produced(%s) internally, expected(%s) for(%s)\n",
        strhex,hexf,in);
  }; /* fi */
}else{
  bad++;
  printf("15:sscanf( %%G) was unable to do(%s)\n",in);
};/* fi */
/*----------------------------- Test doubles --------------------------*/
dd = PI;
i = sscanf(in,"%le",&dd);
if(i==1){
  hexer_8(strhex,&dd);
  if(strcmp(hexd,strhex)==0){
  ; sprintf(strout,"%.0e",dd);
  ; if(strcmp(doute,strout)==0){
  ;   ok++;
#ifdef ECHO_GOOD
  ;   printf("OK: (%s) -> (%s) as (%s)\n",in,doute,hexd);
#endif
  ; }else{
  ;   bad++;
  ;   printf("16:sprintf( %%e) produced(%s), expected(%s) for(%s)\n",
        strout,doute,in);
  ; }; /* fi */
  }else{
  ; bad++;
  ; printf("17:sscanf(%%le) produced(%s) internally, expected(%s) for(%s)\n",
        strhex,hexd,in);
  }; /* fi */
}else{
  bad++;
  printf("18:sscanf(%%le) was unable to do(%s)\n",in);
};/* fi */
 
dd = PI;
i = sscanf(in,"%lE",&dd);
if(i==1){
  hexer_8(strhex,&dd);
  if(strcmp(hexd,strhex)==0){
  ; sprintf(strout,"%.0E",dd);
  ; if(strcmp(doutE,strout)==0){
  ;   ok++;
#ifdef ECHO_GOOD
  ;   printf("OK: (%s) -> (%s) as (%s)\n",in,doutE,hexd);
#endif
  ; }else{
  ;   bad++;
  ;   printf("19:sprintf( %%E) produced(%s), expected(%s) for(%s)\n",
        strout,doutE,in);
  ; }; /* fi */
  }else{
  ; bad++;
  ; printf("20:sscanf(%%lE) produced(%s) internally, expected(%s) for(%s)\n",
        strhex,hexd,in);
  }; /* fi */
}else{
  bad++;
  printf("21:sscanf(%%lE) was unable to do(%s)\n",in);
};/* fi */
 
dd = PI;
i = sscanf(in,"%lf",&dd);
if(i==1){
  hexer_8(strhex,&dd);
  if(strcmp(hexd,strhex)==0){
  ; sprintf(strout,"%.0f",dd);
  ; if(strcmp(doutfgG,strout)==0){
  ;   ok++;
#ifdef ECHO_GOOD
  ;   printf("OK: (%s) -> (%s) as (%s)\n",in,doutfgG,hexd);
#endif
  ; }else{
  ;   bad++;
  ;   printf("22:sprintf( %%f) produced(%s), expected(%s) for(%s)\n",
        strout,doutfgG,in);
  ; }; /* fi */
  }else{
  ; bad++;
  ; printf("23:sscanf(%%lf) produced(%s) internally, expected(%s) for(%s)\n",
        strhex,hexd,in);
  }; /* fi */
}else{
  bad++;
  printf("24:sscanf(%%lf) was unable to do(%s)\n",in);
};/* fi */
 
dd = PI;
i = sscanf(in,"%lg",&dd);
if(i==1){
  hexer_8(strhex,&dd);
  if(strcmp(hexd,strhex)==0){
  ; sprintf(strout,"%.0g",dd);
  ; if(strcmp(doutfgG,strout)==0){
  ;   ok++;
#ifdef ECHO_GOOD
  ;   printf("OK: (%s) -> (%s) as (%s)\n",in,doutfgG,hexd);
#endif
  ; }else{
  ;   bad++;
  ;   printf("25:sprintf( %%g) produced(%s), expected(%s) for(%s)\n",
        strout,doutfgG,in);
  ; }; /* fi */
  }else{
  ; bad++;
  ; printf("26:sscanf(%%lg) produced(%s) internally, expected(%s) for(%s)\n",
        strhex,hexd,in);
  }; /* fi */
}else{
  bad++;
  printf("27:sscanf(%%lg) was unable to do(%s)\n",in);
};/* fi */
 
dd = PI;
i = sscanf(in,"%lG",&dd);
if(i==1){
  hexer_8(strhex,&dd);
  if(strcmp(hexd,strhex)==0){
  ; sprintf(strout,"%.0G",dd);
  ; if(strcmp(doutfgG,strout)==0){
  ;   ok++;
#ifdef ECHO_GOOD
  ;   printf("OK: (%s) -> (%s) as (%s)\n",in,doutfgG,hexd);
#endif
  ; }else{
  ;   bad++;
  ;   printf("28:sprintf( %%G) produced(%s), expected(%s) for(%s)\n",
        strout,doutfgG,in);
  ; }; /* fi */
  }else{
  ; bad++;
  ; printf("29:sscanf(%%lG) produced(%s) internally, expected(%s) for(%s)\n",
        strhex,hexd,in);
  }; /* fi */
}else{
  bad++;
  printf("30:sscanf(%%lG) was unable to do(%s)\n",in);
};/* fi */
 
dd = PI;
dd = atof(in);
if(dd!=PI){
  hexer_8(strhex,&dd);
  if(strcmp(hexd,strhex)==0){
  ; ok++;
#ifdef ECHO_GOOD
  ; printf("OK: (%s) -> (%s) as (%s)\n",in,doutfgG,hexd);
#endif
  }else{
  ; bad++;
  ; printf("31:atof produced(%s) internally, expected(%s) for(%s)\n",
        strhex,hexd,in);
  }; /* fi */
}else{
  bad++;
  printf("32:atof was unable to do(%s)\n",in);
};/* fi */
 
dd = PI;
dd = strtod(in, &c_ptr);
if(dd!=PI){
  hexer_8(strhex,&dd);
  if(strcmp(hexd,strhex)==0){
  ; if( (c_ptr!=in) & (strch == *c_ptr) ){
  ;   ok++;
#ifdef ECHO_GOOD
  ;   printf("OK: (%s) -> (%s) as (%s)\n",in,doutfgG,hexd);
#endif
  ; }else{
  ;   bad++;
  ;   printf("33:strtod scanned wrong: found(%#x), expected(%#x) for(%s)\n",
          (unsigned int)*c_ptr, (unsigned int)strch, in);
  ; }; /* fi */
  }else{
  ; bad++;
  ; printf("34:strtod produced(%s) internally, expected(%s) for(%s)\n",
        strhex,hexd,in);
  }; /* fi */
}else{
  bad++;
  printf("35:strtod was unable to do(%s)\n",in);
};/* fi */
 
#ifdef CVT
  gcvt(dd,17,strout);
  if(strcmp(doutfgG,strout)==0){
    ok++;
#ifdef ECHO_GOOD
    printf("OK: (%s) -> (%s) as (%s)\n",in,doutfgG,hexd);
#endif
  }else{
    bad++;
    printf("36:gcvt produced(%s), expected(%s) for(%s)\n",
      strout,doutfgG,in);
  }; /* fi */
#endif /* CVT */
} /* end test */
/*=====================================================================*/
main()
{
  float w;
  float x;
  float y;
  float z;
 double ww;
 double xx;
 double yy;
 double zz;
 double si;
#if 0
printf("From ANSI/IEEE Standard for Radix-Independent\n");
printf("Floating-Point Arithmetic; Std. 854-1987:    \n");
printf("Section 5.6 Floating-Point <-> Decimal String Conversion:\n");
printf("Overflow/underflow and NaNs and infinities encountered\n");
printf("during floating-point to decimal string conversion should\n");
printf("be indicated to the user by appropriate strings.  The\n");
printf("letters 'NaN,' case insensitive, optionally preceded by\n");
printf("an algebraic sign, should be the first characters of a\n");
printf("string representing a NaN.  The remainder of the string\n");
printf("may be used for system-dependent information on output,\n");
printf("and may be ignored on input.  Unless recognized as a\n");
printf("quiet NaN on input, an input NaN should become a signaling\n");
printf("NaN.  The letters 'inf' or 'infinity,' case insensitive,\n");
printf("optionally preceded by an algebraic sign, should be the\n");
printf("characters representing signed infinity.  Either\n");
printf("representation may be produced on output; both should be\n");
printf("accepted on input.\n");
printf("To get a copy of the standards:\n");
printf("  Phone 9-1-800-678-IEEE, tell them your VISA/M.C. number.\n");
printf("    SH11460 - IEEE 854-1987 Radix-Independent Floating-Point\n");
printf("    SH10116 - IEEE 754-1985 Binary Floating-Point Arithmetic\n");
#endif
 
ok = bad = 0;
 
w = 1.0f;              /* Determine how numbers are stored internally. */
byte_order = LITTLE_ENDIAN;
hexer_4( s,&w);   /* convert internal to char */
if( strcmp( s, spONE ) != 0 ){
    byte_order = BIG_ENDIAN;
    hexer_4(ss,&w);   /* convert internal to char */
    if( strcmp(ss, spONE ) != 0 ){
        printf("\n45: Unable to determine how numbers are stored.\n");
    };
};
 
z = 0.0F;                       /* floats */
x = 1.0F/z;  /* +infinity */
y = -x;      /* -infinity */
w = 0.0F/z;  /* -QNaN = real indefinite on a 80387 */
z = -w;      /* +QNaN */
 
zz= 0.0;                        /* doubles */
xx= 1.0/zz;  /* +infinity */
yy= -xx;     /* -infinity */
ww= 0.0/zz;  /* -QNaN = real indefinite on a 80387 */
zz= -ww;     /* +QNaN */
 
printf("\nFirst list how infinity and Quiet-NaN are done:\n");
printf("<%9g>(%s) <%9g>(%s)\n",x,hexer_4(s,&x),xx,hexer_8(ss,&xx));
printf("<%9g>(%s) <%9g>(%s)\n",y,hexer_4(s,&y),yy,hexer_8(ss,&yy));
printf("<%9g>(%s) <%9g>(%s)\n",z,hexer_4(s,&z),zz,hexer_8(ss,&zz));
printf("<%9g>(%s) <%9g>(%s)\n",w,hexer_4(s,&w),ww,hexer_8(ss,&ww));
 
printf("\nCheck for support of signed NaNs:\n");
hexer_4( s,&w);   /* convert internal to char */
hexer_4(ss,&z);
if( strcmp( s, ss ) == 0 ){
  bad++;
  printf("50:-NaNQ is same as +NaNQ, internally in float\n");
}else{
  ok++;
#ifdef ECHO_GOOD
  printf("OK: -NaNQ is different than +NaNQ, as a float.\n");
#endif
};
 
hexer_8( s,&ww);   /* convert internal to char */
hexer_8(ss,&zz);
if( strcmp( s, ss ) == 0 ){
  bad++;
  printf("51:-NaNQ is same as +NaNQ, internally in double\n");
}else{
  ok++;
#ifdef ECHO_GOOD
  printf("OK: -NaNQ is different than +NaNQ, as a double.\n");
#endif
};
 
printf("\nCheck on NaNs of sscanf vs internal math (ignore signs):\n");
si = PI;
sscanf("-NaNQ","%le",&si);
hexer_8( s,&si);   /* convert internal to char */
hexer_8(ss,&zz);
if(  s[2] == 'f' ){  s[2] = '7'; };    /* absolute value */
if( ss[2] == 'f' ){ ss[2] = '7'; };
if( strcmp( s, ss ) != 0 ){
  bad++;
  printf("00:sscanf produced(%s) for Quiet-Nan;\n", s);
  printf("  (0./0.) produced(%s)\n", ss);
}else{
  ok++;
#ifdef ECHO_GOOD
  printf("OK: sscanf(Quiet-Nan) == 0./0.\n");
#endif
};
 
printf("\nThe order of the following tests is:\n");
printf("  Mixed case, UPPER case, lower case, +case, -case\n");
#ifdef CVT
printf("    Each case is tested 13 ways:\n");
#else
printf("    Each case is tested 12 ways:\n");
#endif
printf("      sscanf/sprintf:  e,  E,  f,  g,  G: float\n");
printf("      sscanf/sprintf: le, lE, lf, lg, lG: double\n");
#ifdef CVT
printf("      atof, strtod, gcvt: double\n");
#else
printf("      atof, strtod: double\n");
#endif
 
printf("\nINF - part of ANSI/IEEE Std. 854-1987\n");
test( "Inf",dpINF,spINF,dpInf,dpInf,dpInf,spInf,spInf,spInf,Nul);
test( "INF",dpINF,spINF,dpInf,dpInf,dpInf,spInf,spInf,spInf,Nul);
test( "inf",dpINF,spINF,dpInf,dpInf,dpInf,spInf,spInf,spInf,Nul);
test("+INF",dpINF,spINF,dpInf,dpInf,dpInf,spInf,spInf,spInf,Nul);
test("-INF",dmINF,smINF,dmInf,dmInf,dmInf,smInf,smInf,smInf,Nul);
 
printf("\ninfinity - part of ANSI/IEEE Std. 854-1987\n");
test( "Infinity",dpINF,spINF,dpInf,dpInf,dpInf,spInf,spInf,spInf,Nul);
test( "INFINITY",dpINF,spINF,dpInf,dpInf,dpInf,spInf,spInf,spInf,Nul);
test( "infinity",dpINF,spINF,dpInf,dpInf,dpInf,spInf,spInf,spInf,Nul);
test("+infinity",dpINF,spINF,dpInf,dpInf,dpInf,spInf,spInf,spInf,Nul);
test("-infinity",dmINF,smINF,dmInf,dmInf,dmInf,smInf,smInf,smInf,Nul);
 
printf("\ninfinite - part of ANSI/IEEE Std. 854-1987\n");
test( "Infinite",dpINF,spINF,dpInf,dpInf,dpInf,spInf,spInf,spInf,'i');
test( "INFINITE",dpINF,spINF,dpInf,dpInf,dpInf,spInf,spInf,spInf,'I');
test( "infinite",dpINF,spINF,dpInf,dpInf,dpInf,spInf,spInf,spInf,'i');
test("+infinite",dpINF,spINF,dpInf,dpInf,dpInf,spInf,spInf,spInf,'i');
test("-infinite",dmINF,smINF,dmInf,dmInf,dmInf,smInf,smInf,smInf,'i');
 
printf("\n1e999999 - another form of infinity\n");
test( "1e999999",dpINF,spINF,dpInf,dpInf,dpInf,spInf,spInf,spInf,Nul);
test( "1E999999",dpINF,spINF,dpInf,dpInf,dpInf,spInf,spInf,spInf,Nul);
test("1e+999999",dpINF,spINF,dpInf,dpInf,dpInf,spInf,spInf,spInf,Nul);
test("+1e999999",dpINF,spINF,dpInf,dpInf,dpInf,spInf,spInf,spInf,Nul);
test("-1e999999",dmINF,smINF,dmInf,dmInf,dmInf,smInf,smInf,smInf,Nul);
 
printf("\n1e4294967296 = (2**32) - another form of infinity\n");
test( "1e4294967296",dpINF,spINF,dpInf,dpInf,dpInf,spInf,spInf,spInf,\
       Nul);
test( "1E4294967296",dpINF,spINF,dpInf,dpInf,dpInf,spInf,spInf,spInf,\
       Nul);
test("1e+4294967296",dpINF,spINF,dpInf,dpInf,dpInf,spInf,spInf,spInf,\
       Nul);
test("+1e4294967296",dpINF,spINF,dpInf,dpInf,dpInf,spInf,spInf,spInf,\
       Nul);
test("-1e4294967296",dmINF,smINF,dmInf,dmInf,dmInf,smInf,smInf,smInf,\
       Nul);
 
printf("\n1e4294967264 = (2**32 - 32) - another form of infinity\n");
test( "1e4294967264",dpINF,spINF,dpInf,dpInf,dpInf,spInf,spInf,spInf,\
      Nul);
test( "1E4294967264",dpINF,spINF,dpInf,dpInf,dpInf,spInf,spInf,spInf,\
      Nul);
test("1e+4294967264",dpINF,spINF,dpInf,dpInf,dpInf,spInf,spInf,spInf,\
      Nul);
test("+1e4294967264",dpINF,spINF,dpInf,dpInf,dpInf,spInf,spInf,spInf,\
      Nul);
test("-1e4294967264",dmINF,smINF,dmInf,dmInf,dmInf,smInf,smInf,smInf,\
      Nul);
 
printf("\nNaN - part of ANSI/IEEE Std. 854-1987\n");
test( "NaN",dpNANS,spNANS,dpNS,dpNS,dpNS,spNS,spNS,spNS,Nul);
test( "NAN",dpNANS,spNANS,dpNS,dpNS,dpNS,spNS,spNS,spNS,Nul);
test( "nan",dpNANS,spNANS,dpNS,dpNS,dpNS,spNS,spNS,spNS,Nul);
test("+NaN",dpNANS,spNANS,dpNS,dpNS,dpNS,spNS,spNS,spNS,Nul);
test("-NaN",dmNANS,smNANS,dmNS,dmNS,dmNS,smNS,smNS,smNS,Nul);
 
printf("\nNaNS - part of ANSI/IEEE Std. 854-1987\n");
test( "NaNS",dpNANS,spNANS,dpNS,dpNS,dpNS,spNS,spNS,spNS,Nul);
test( "NANS",dpNANS,spNANS,dpNS,dpNS,dpNS,spNS,spNS,spNS,Nul);
test( "nans",dpNANS,spNANS,dpNS,dpNS,dpNS,spNS,spNS,spNS,Nul);
test("+NaNS",dpNANS,spNANS,dpNS,dpNS,dpNS,spNS,spNS,spNS,Nul);
test("-NaNS",dmNANS,smNANS,dmNS,dmNS,dmNS,smNS,smNS,smNS,Nul);
 
printf("\nNaNQ - part of ANSI/IEEE Std. 854-1987\n");
test( "NaNQ",dpNANQ,spNANQ,dpNQ,dpNQ,dpNQ,spNQ,spNQ,spNQ,Nul);
test( "NANQ",dpNANQ,spNANQ,dpNQ,dpNQ,dpNQ,spNQ,spNQ,spNQ,Nul);
test( "nanq",dpNANQ,spNANQ,dpNQ,dpNQ,dpNQ,spNQ,spNQ,spNQ,Nul);
test("+NaNQ",dpNANQ,spNANQ,dpNQ,dpNQ,dpNQ,spNQ,spNQ,spNQ,Nul);
test("-NaNQ",dmNANQ,smNANQ,dmNQ,dmNQ,dmNQ,smNQ,smNQ,smNQ,Nul);
 
printf("\nNaN() - a way to do other values of NaN\n");
test( "NaN()",dpNANS,spNANS,dpNS,dpNS,dpNS,spNS,spNS,spNS,'(');
test( "NAN()",dpNANS,spNANS,dpNS,dpNS,dpNS,spNS,spNS,spNS,'(');
test( "nan()",dpNANS,spNANS,dpNS,dpNS,dpNS,spNS,spNS,spNS,'(');
test("+NaN()",dpNANS,spNANS,dpNS,dpNS,dpNS,spNS,spNS,spNS,'(');
test("-NaN()",dmNANS,smNANS,dmNS,dmNS,dmNS,smNS,smNS,smNS,'(');
 
printf("\n1/0 - part of IEEE 854 draft 1.0 -- not in final standard\n");
test( "1/0",dpONE,spONE, "1", "1e+00", "1E+00", "1", "1e+00",\
        "1E+00",'/');
test("1/+0",dpONE,spONE, "1", "1e+00", "1E+00", "1", "1e+00",\
        "1E+00",'/');
test("1/-0",dpONE,spONE, "1", "1e+00", "1E+00", "1", "1e+00",\
        "1E+00",'/');
test("+1/0",dpONE,spONE, "1", "1e+00", "1E+00", "1", "1e+00",\
        "1E+00",'/');
test("-1/0",dmONE,smONE,"-1","-1e+00","-1E+00","-1","-1e+00",\
       "-1E+00",'/');
 
printf("\n0/0 - alternate form of NaN -- not in standards.\n");
test( "0/0",dpZERO,spZERO, "0", "0e+00", "0E+00", "0", "0e+00", "0E+00",\
           '/');
test("0/+0",dpZERO,spZERO, "0", "0e+00", "0E+00", "0", "0e+00", "0E+00",\
           '/');
test("0/-0",dpZERO,spZERO, "0", "0e+00", "0E+00", "0", "0e+00", "0E+00",\
           '/');
test("+0/0",dpZERO,spZERO, "0", "0e+00", "0E+00", "0", "0e+00", "0E+00",\
           '/');
test("-0/0",dmZERO,smZERO,"-0","-0e+00","-0E+00","-0","-0e+00","-0E+00",\
           '/');
 
printf("\n1e+ 99999 - strange form of 1.0, not infinity.\n");
test( "1e 99999", dpONE,spONE, "1", "1e+00", "1E+00", "1", "1e+00",\
         "1E+00",'e');
test( "1e+ 99999",dpONE,spONE, "1", "1e+00", "1E+00", "1", "1e+00",\
         "1E+00",'e');
test( "1E+ 99999",dpONE,spONE, "1", "1e+00", "1E+00", "1", "1e+00",\
         "1E+00",'E');
test("+1e+ 99999",dpONE,spONE, "1", "1e+00", "1E+00", "1", "1e+00",\
         "1E+00",'e');
test("-1e+ 99999",dmONE,smONE,"-1","-1e+00","-1E+00","-1","-1e+00",\
        "-1E+00",'e');
 
printf("\n%d OK, %d bad\n",ok,bad);
}



More information about the Numeric-interest mailing list