c88250a57d
problems relating to NaNs and rounding.
111 lines
3.3 KiB
C
111 lines
3.3 KiB
C
/****************************************************************
|
|
|
|
The author of this software is David M. Gay.
|
|
|
|
Copyright (C) 2005 by David M. Gay
|
|
All Rights Reserved
|
|
|
|
Permission to use, copy, modify, and distribute this software and its
|
|
documentation for any purpose and without fee is hereby granted,
|
|
provided that the above copyright notice appear in all copies and that
|
|
both that the copyright notice and this permission notice and warranty
|
|
disclaimer appear in supporting documentation, and that the name of
|
|
the author or any of his current or former employers not be used in
|
|
advertising or publicity pertaining to distribution of the software
|
|
without specific, written prior permission.
|
|
|
|
THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
|
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
|
|
NO EVENT SHALL THE AUTHOR OR ANY OF HIS CURRENT OR FORMER EMPLOYERS 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.
|
|
|
|
****************************************************************/
|
|
|
|
/* Please send bug reports to David M. Gay (dmg at acm dot org,
|
|
* with " at " changed at "@" and " dot " changed to "."). */
|
|
|
|
/* Program to compute quiet NaNs of various precisions (float, */
|
|
/* double, and perhaps long double) on the current system, */
|
|
/* provided the system uses binary IEEE (P754) arithmetic. */
|
|
/* Note that one system's quiet NaN may be a signaling NaN on */
|
|
/* another system. The IEEE arithmetic standards (P754, P854) */
|
|
/* do not specify how to distinguish signaling NaNs from quiet */
|
|
/* ones, and this detail varies across systems. The computed */
|
|
/* NaN values are encoded in #defines for values for an */
|
|
/* unsigned 32-bit integer type, called Ulong below, and */
|
|
/* (for long double) perhaps as unsigned short values. Once */
|
|
/* upon a time, there were PC compilers for Intel CPUs that */
|
|
/* had sizeof(long double) = 10. Are such compilers still */
|
|
/* distributed? */
|
|
|
|
#include <stdio.h>
|
|
#include "arith.h"
|
|
|
|
#ifndef Long
|
|
#define Long long
|
|
#endif
|
|
|
|
typedef unsigned Long Ulong;
|
|
|
|
#undef HAVE_IEEE
|
|
#ifdef IEEE_8087
|
|
#define _0 1
|
|
#define _1 0
|
|
#define HAVE_IEEE
|
|
#endif
|
|
#ifdef IEEE_MC68k
|
|
#define _0 0
|
|
#define _1 1
|
|
#define HAVE_IEEE
|
|
#endif
|
|
|
|
#define UL (unsigned long)
|
|
|
|
int
|
|
main(void)
|
|
{
|
|
#ifdef HAVE_IEEE
|
|
typedef union {
|
|
float f;
|
|
double d;
|
|
Ulong L[4];
|
|
#ifndef NO_LONG_LONG
|
|
unsigned short u[5];
|
|
long double D;
|
|
#endif
|
|
} U;
|
|
U a, b, c;
|
|
int i;
|
|
|
|
a.L[0] = b.L[0] = 0x7f800000;
|
|
c.f = a.f - b.f;
|
|
printf("#define f_QNAN 0x%lx\n", UL c.L[0]);
|
|
a.L[_0] = b.L[_0] = 0x7ff00000;
|
|
a.L[_1] = b.L[_1] = 0;
|
|
c.d = a.d - b.d; /* quiet NaN */
|
|
printf("#define d_QNAN0 0x%lx\n", UL c.L[0]);
|
|
printf("#define d_QNAN1 0x%lx\n", UL c.L[1]);
|
|
#ifdef NO_LONG_LONG
|
|
for(i = 0; i < 4; i++)
|
|
printf("#define ld_QNAN%d 0xffffffff\n", i);
|
|
for(i = 0; i < 5; i++)
|
|
printf("#define ldus_QNAN%d 0xffff\n", i);
|
|
#else
|
|
b.D = c.D = a.d;
|
|
if (printf("") < 0)
|
|
c.D = 37; /* never executed; just defeat optimization */
|
|
a.L[2] = a.L[3] = 0;
|
|
a.D = b.D - c.D;
|
|
for(i = 0; i < 4; i++)
|
|
printf("#define ld_QNAN%d 0x%lx\n", i, UL a.L[i]);
|
|
for(i = 0; i < 5; i++)
|
|
printf("#define ldus_QNAN%d 0x%x\n", i, a.u[i]);
|
|
#endif
|
|
#endif /* HAVE_IEEE */
|
|
return 0;
|
|
}
|