1 /*	A C version of Kahan's Floating Point Test "Paranoia"
2 
3 Thos Sumner, UCSF, Feb. 1985
4 David Gay, BTL, Jan. 1986
5 
6 This is a rewrite from the Pascal version by
7 
8 B. A. Wichmann, 18 Jan. 1985
9 
10 (and does NOT exhibit good C programming style).
11 
12 Adjusted to use Standard C headers 19 Jan. 1992 (dmg);
13 
14 (C) Apr 19 1983 in BASIC version by:
15 Professor W. M. Kahan,
16 567 Evans Hall
17 Electrical Engineering & Computer Science Dept.
18 University of California
19 Berkeley, California 94720
20 USA
21 
22 converted to Pascal by:
23 B. A. Wichmann
24 National Physical Laboratory
25 Teddington Middx
26 TW11 OLW
27 UK
28 
29 converted to C by:
30 
31 David M. Gay		and	Thos Sumner
32 AT&T Bell Labs			Computer Center, Rm. U-76
33 600 Mountain Avenue		University of California
34 Murray Hill, NJ 07974		San Francisco, CA 94143
35 USA				USA
36 
37 with simultaneous corrections to the Pascal source (reflected
38 in the Pascal source available over netlib).
39 [A couple of bug fixes from dgh = sun!dhough incorporated 31 July 1986.]
40 
41 Reports of results on various systems from all the versions
42 of Paranoia are being collected by Richard Karpinski at the
43 same address as Thos Sumner.  This includes sample outputs,
44 bug reports, and criticisms.
45 
46 You may copy this program freely if you acknowledge its source.
47 Comments on the Pascal version to NPL, please.
48 
49 The following is from the introductory commentary from Wichmann's work:
50 
51 The BASIC program of Kahan is written in Microsoft BASIC using many
52 facilities which have no exact analogy in Pascal.  The Pascal
53 version below cannot therefore be exactly the same.  Rather than be
54 a minimal transcription of the BASIC program, the Pascal coding
55 follows the conventional style of block-structured languages.  Hence
56 the Pascal version could be useful in producing versions in other
57 structured languages.
58 
59 Rather than use identifiers of minimal length (which therefore have
60 little mnemonic significance), the Pascal version uses meaningful
61 identifiers as follows [Note: A few changes have been made for C]:
62 
63 
64 BASIC   C               BASIC   C               BASIC   C
65 
66 A                       J                       S    StickyBit
67 A1   AInverse           J0   NoErrors           T
68 B    Radix                    [Failure]         T0   Underflow
69 B1   BInverse           J1   NoErrors           T2   ThirtyTwo
70 B2   RadixD2                  [SeriousDefect]   T5   OneAndHalf
71 B9   BMinusU2           J2   NoErrors           T7   TwentySeven
72 C                             [Defect]          T8   TwoForty
73 C1   CInverse           J3   NoErrors           U    OneUlp
74 D                             [Flaw]            U0   UnderflowThreshold
75 D4   FourD              K    PageNo             U1
76 E0                      L    Milestone          U2
77 E1                      M                       V
78 E2   Exp2               N                       V0
79 E3                      N1                      V8
80 E5   MinSqEr            O    Zero               V9
81 E6   SqEr               O1   One                W
82 E7   MaxSqEr            O2   Two                X
83 E8                      O3   Three              X1
84 E9                      O4   Four               X8
85 F1   MinusOne           O5   Five               X9   Random1
86 F2   Half               O8   Eight              Y
87 F3   Third              O9   Nine               Y1
88 F6                      P    Precision          Y2
89 F9                      Q                       Y9   Random2
90 G1   GMult              Q8                      Z
91 G2   GDiv               Q9                      Z0   PseudoZero
92 G3   GAddSub            R                       Z1
93 H                       R1   RMult              Z2
94 H1   HInverse           R2   RDiv               Z9
95 I                       R3   RAddSub
96 IO   NoTrials           R4   RSqrt
97 I3   IEEE               R9   Random9
98 
99 SqRWrng
100 
101 All the variables in BASIC are true variables and in consequence,
102 the program is more difficult to follow since the "constants" must
103 be determined (the glossary is very helpful).  The Pascal version
104 uses Real constants, but checks are added to ensure that the values
105 are correctly converted by the compiler.
106 
107 The major textual change to the Pascal version apart from the
108 identifiersis that named procedures are used, inserting parameters
109 wherehelpful.  New procedures are also introduced.  The
110 correspondence is as follows:
111 
112 
113 BASIC       Pascal
114 lines
115 
116 90- 140   Pause
117 170- 250   Instructions
118 380- 460   Heading
119 480- 670   Characteristics
120 690- 870   History
121 2940-2950   Random
122 3710-3740   NewD
123 4040-4080   DoesYequalX
124 4090-4110   PrintIfNPositive
125 4640-4850   TestPartialUnderflow
126 
127 */
128 
129   /* This version of paranoia has been modified to work with GCC's internal
130      software floating point emulation library, as a sanity check of same.
131 
132      I'm doing this in C++ so that I can do operator overloading and not
133      have to modify so damned much of the existing code.  */
134 
135   extern "C" {
136 #include <stdio.h>
137 #include <stddef.h>
138 #include <limits.h>
139 #include <string.h>
140 #include <stdlib.h>
141 #include <math.h>
142 #include <unistd.h>
143 #include <float.h>
144 
145     /* This part is made all the more awful because many gcc headers are
146        not prepared at all to be parsed as C++.  The biggest stickler
147        here is const structure members.  So we include exactly the pieces
148        that we need.  */
149 
150 #define GTY(x)
151 
152 #include "ansidecl.h"
153 #include "auto-host.h"
154 #include "hwint.h"
155 
156 #undef EXTRA_MODES_FILE
157 
158     struct rtx_def;
159     typedef struct rtx_def *rtx;
160     struct rtvec_def;
161     typedef struct rtvec_def *rtvec;
162     union tree_node;
163     typedef union tree_node *tree;
164 
165 #define DEFTREECODE(SYM, STRING, TYPE, NARGS)   SYM,
166     enum tree_code {
167 #include "tree.def"
168       LAST_AND_UNUSED_TREE_CODE
169     };
170 #undef DEFTREECODE
171 
172 #define class klass
173 
174 #include "real.h"
175 
176 #undef class
177   }
178 
179 /* We never produce signals from the library.  Thus setjmp need do nothing.  */
180 #undef setjmp
181 #define setjmp(x)  (0)
182 
183 static bool verbose = false;
184 static int verbose_index = 0;
185 
186 /* ====================================================================== */
187 /* The implementation of the abstract floating point class based on gcc's
188    real.c.  I.e. the object of this exercise.  Templated so that we can
189    all fp sizes.  */
190 
191 class real_c_float
192 {
193  public:
194   static const enum machine_mode MODE = SFmode;
195 
196  private:
197   static const int external_max = 128 / 32;
198   static const int internal_max
199     = (sizeof (REAL_VALUE_TYPE) + sizeof (long) + 1) / sizeof (long);
200   long image[external_max < internal_max ? internal_max : external_max];
201 
202   void from_long(long);
203   void from_str(const char *);
204   void binop(int code, const real_c_float&);
205   void unop(int code);
206   bool cmp(int code, const real_c_float&) const;
207 
208  public:
real_c_float()209   real_c_float()
210     { }
real_c_float(long l)211   real_c_float(long l)
212     { from_long(l); }
real_c_float(const char * s)213   real_c_float(const char *s)
214     { from_str(s); }
real_c_float(const real_c_float & b)215   real_c_float(const real_c_float &b)
216     { memcpy(image, b.image, sizeof(image)); }
217 
operator =(long l)218   const real_c_float& operator= (long l)
219     { from_long(l); return *this; }
operator =(const char * s)220   const real_c_float& operator= (const char *s)
221     { from_str(s); return *this; }
operator =(const real_c_float & b)222   const real_c_float& operator= (const real_c_float &b)
223     { memcpy(image, b.image, sizeof(image)); return *this; }
224 
operator +=(const real_c_float & b)225   const real_c_float& operator+= (const real_c_float &b)
226     { binop(PLUS_EXPR, b); return *this; }
operator -=(const real_c_float & b)227   const real_c_float& operator-= (const real_c_float &b)
228     { binop(MINUS_EXPR, b); return *this; }
operator *=(const real_c_float & b)229   const real_c_float& operator*= (const real_c_float &b)
230     { binop(MULT_EXPR, b); return *this; }
operator /=(const real_c_float & b)231   const real_c_float& operator/= (const real_c_float &b)
232     { binop(RDIV_EXPR, b); return *this; }
233 
operator -() const234   real_c_float operator- () const
235     { real_c_float r(*this); r.unop(NEGATE_EXPR); return r; }
abs() const236   real_c_float abs () const
237     { real_c_float r(*this); r.unop(ABS_EXPR); return r; }
238 
operator <(const real_c_float & b) const239   bool operator <  (const real_c_float &b) const { return cmp(LT_EXPR, b); }
operator <=(const real_c_float & b) const240   bool operator <= (const real_c_float &b) const { return cmp(LE_EXPR, b); }
operator ==(const real_c_float & b) const241   bool operator == (const real_c_float &b) const { return cmp(EQ_EXPR, b); }
operator !=(const real_c_float & b) const242   bool operator != (const real_c_float &b) const { return cmp(NE_EXPR, b); }
operator >=(const real_c_float & b) const243   bool operator >= (const real_c_float &b) const { return cmp(GE_EXPR, b); }
operator >(const real_c_float & b) const244   bool operator >  (const real_c_float &b) const { return cmp(GT_EXPR, b); }
245 
246   const char * str () const;
247   const char * hex () const;
248   long integer () const;
249   int exp () const;
250   void ldexp (int);
251 };
252 
253 void
from_long(long l)254 real_c_float::from_long (long l)
255 {
256   REAL_VALUE_TYPE f;
257 
258   real_from_integer (&f, MODE, l, l < 0 ? -1 : 0, 0);
259   real_to_target (image, &f, MODE);
260 }
261 
262 void
from_str(const char * s)263 real_c_float::from_str (const char *s)
264 {
265   REAL_VALUE_TYPE f;
266   const char *p = s;
267 
268   if (*p == '-' || *p == '+')
269     p++;
270   if (strcasecmp(p, "inf") == 0)
271     {
272       real_inf (&f);
273       if (*s == '-')
274         real_arithmetic (&f, NEGATE_EXPR, &f, NULL);
275     }
276   else if (strcasecmp(p, "nan") == 0)
277     real_nan (&f, "", 1, MODE);
278   else
279     real_from_string (&f, s);
280 
281   real_to_target (image, &f, MODE);
282 }
283 
284 void
binop(int code,const real_c_float & b)285 real_c_float::binop (int code, const real_c_float &b)
286 {
287   REAL_VALUE_TYPE ai, bi, ri;
288 
289   real_from_target (&ai, image, MODE);
290   real_from_target (&bi, b.image, MODE);
291   real_arithmetic (&ri, code, &ai, &bi);
292   real_to_target (image, &ri, MODE);
293 
294   if (verbose)
295     {
296       char ab[64], bb[64], rb[64];
297       const real_format *fmt = real_format_for_mode[MODE - QFmode];
298       const int digits = (fmt->p * fmt->log2_b + 3) / 4;
299       char symbol_for_code;
300 
301       real_from_target (&ri, image, MODE);
302       real_to_hexadecimal (ab, &ai, sizeof(ab), digits, 0);
303       real_to_hexadecimal (bb, &bi, sizeof(bb), digits, 0);
304       real_to_hexadecimal (rb, &ri, sizeof(rb), digits, 0);
305 
306       switch (code)
307 	{
308 	case PLUS_EXPR:
309 	  symbol_for_code = '+';
310 	  break;
311 	case MINUS_EXPR:
312 	  symbol_for_code = '-';
313 	  break;
314 	case MULT_EXPR:
315 	  symbol_for_code = '*';
316 	  break;
317 	case RDIV_EXPR:
318 	  symbol_for_code = '/';
319 	  break;
320 	default:
321 	  abort ();
322 	}
323 
324       fprintf (stderr, "%6d: %s %c %s = %s\n", verbose_index++,
325 	       ab, symbol_for_code, bb, rb);
326     }
327 }
328 
329 void
unop(int code)330 real_c_float::unop (int code)
331 {
332   REAL_VALUE_TYPE ai, ri;
333 
334   real_from_target (&ai, image, MODE);
335   real_arithmetic (&ri, code, &ai, NULL);
336   real_to_target (image, &ri, MODE);
337 
338   if (verbose)
339     {
340       char ab[64], rb[64];
341       const real_format *fmt = real_format_for_mode[MODE - QFmode];
342       const int digits = (fmt->p * fmt->log2_b + 3) / 4;
343       const char *symbol_for_code;
344 
345       real_from_target (&ri, image, MODE);
346       real_to_hexadecimal (ab, &ai, sizeof(ab), digits, 0);
347       real_to_hexadecimal (rb, &ri, sizeof(rb), digits, 0);
348 
349       switch (code)
350 	{
351 	case NEGATE_EXPR:
352 	  symbol_for_code = "-";
353 	  break;
354 	case ABS_EXPR:
355 	  symbol_for_code = "abs ";
356 	  break;
357 	default:
358 	  abort ();
359 	}
360 
361       fprintf (stderr, "%6d: %s%s = %s\n", verbose_index++,
362 	       symbol_for_code, ab, rb);
363     }
364 }
365 
366 bool
cmp(int code,const real_c_float & b) const367 real_c_float::cmp (int code, const real_c_float &b) const
368 {
369   REAL_VALUE_TYPE ai, bi;
370   bool ret;
371 
372   real_from_target (&ai, image, MODE);
373   real_from_target (&bi, b.image, MODE);
374   ret = real_compare (code, &ai, &bi);
375 
376   if (verbose)
377     {
378       char ab[64], bb[64];
379       const real_format *fmt = real_format_for_mode[MODE - QFmode];
380       const int digits = (fmt->p * fmt->log2_b + 3) / 4;
381       const char *symbol_for_code;
382 
383       real_to_hexadecimal (ab, &ai, sizeof(ab), digits, 0);
384       real_to_hexadecimal (bb, &bi, sizeof(bb), digits, 0);
385 
386       switch (code)
387 	{
388 	case LT_EXPR:
389 	  symbol_for_code = "<";
390 	  break;
391 	case LE_EXPR:
392 	  symbol_for_code = "<=";
393 	  break;
394 	case EQ_EXPR:
395 	  symbol_for_code = "==";
396 	  break;
397 	case NE_EXPR:
398 	  symbol_for_code = "!=";
399 	  break;
400 	case GE_EXPR:
401 	  symbol_for_code = ">=";
402 	  break;
403 	case GT_EXPR:
404 	  symbol_for_code = ">";
405 	  break;
406 	default:
407 	  abort ();
408 	}
409 
410       fprintf (stderr, "%6d: %s %s %s = %s\n", verbose_index++,
411 	       ab, symbol_for_code, bb, (ret ? "true" : "false"));
412     }
413 
414   return ret;
415 }
416 
417 const char *
str() const418 real_c_float::str() const
419 {
420   REAL_VALUE_TYPE f;
421   const real_format *fmt = real_format_for_mode[MODE - QFmode];
422   const int digits = int(fmt->p * fmt->log2_b * .30102999566398119521 + 1);
423 
424   real_from_target (&f, image, MODE);
425   char *buf = new char[digits + 10];
426   real_to_decimal (buf, &f, digits+10, digits, 0);
427 
428   return buf;
429 }
430 
431 const char *
hex() const432 real_c_float::hex() const
433 {
434   REAL_VALUE_TYPE f;
435   const real_format *fmt = real_format_for_mode[MODE - QFmode];
436   const int digits = (fmt->p * fmt->log2_b + 3) / 4;
437 
438   real_from_target (&f, image, MODE);
439   char *buf = new char[digits + 10];
440   real_to_hexadecimal (buf, &f, digits+10, digits, 0);
441 
442   return buf;
443 }
444 
445 long
integer() const446 real_c_float::integer() const
447 {
448   REAL_VALUE_TYPE f;
449   real_from_target (&f, image, MODE);
450   return real_to_integer (&f);
451 }
452 
453 int
exp() const454 real_c_float::exp() const
455 {
456   REAL_VALUE_TYPE f;
457   real_from_target (&f, image, MODE);
458   return real_exponent (&f);
459 }
460 
461 void
ldexp(int exp)462 real_c_float::ldexp (int exp)
463 {
464   REAL_VALUE_TYPE ai;
465 
466   real_from_target (&ai, image, MODE);
467   real_ldexp (&ai, &ai, exp);
468   real_to_target (image, &ai, MODE);
469 }
470 
471 /* ====================================================================== */
472 /* An implementation of the abstract floating point class that uses native
473    arithmetic.  Exists for reference and debugging.  */
474 
475 template<typename T>
476 class native_float
477 {
478  private:
479   // Force intermediate results back to memory.
480   volatile T image;
481 
482   static T from_str (const char *);
483   static T do_abs (T);
484   static T verbose_binop (T, char, T, T);
485   static T verbose_unop (const char *, T, T);
486   static bool verbose_cmp (T, const char *, T, bool);
487 
488  public:
native_float()489   native_float()
490     { }
native_float(long l)491   native_float(long l)
492     { image = l; }
native_float(const char * s)493   native_float(const char *s)
494     { image = from_str(s); }
native_float(const native_float & b)495   native_float(const native_float &b)
496     { image = b.image; }
497 
operator =(long l)498   const native_float& operator= (long l)
499     { image = l; return *this; }
operator =(const char * s)500   const native_float& operator= (const char *s)
501     { image = from_str(s); return *this; }
operator =(const native_float & b)502   const native_float& operator= (const native_float &b)
503     { image = b.image; return *this; }
504 
operator +=(const native_float & b)505   const native_float& operator+= (const native_float &b)
506     {
507       image = verbose_binop(image, '+', b.image, image + b.image);
508       return *this;
509     }
operator -=(const native_float & b)510   const native_float& operator-= (const native_float &b)
511     {
512       image = verbose_binop(image, '-', b.image, image - b.image);
513       return *this;
514     }
operator *=(const native_float & b)515   const native_float& operator*= (const native_float &b)
516     {
517       image = verbose_binop(image, '*', b.image, image * b.image);
518       return *this;
519     }
operator /=(const native_float & b)520   const native_float& operator/= (const native_float &b)
521     {
522       image = verbose_binop(image, '/', b.image, image / b.image);
523       return *this;
524     }
525 
operator -() const526   native_float operator- () const
527     {
528       native_float r;
529       r.image = verbose_unop("-", image, -image);
530       return r;
531     }
abs() const532   native_float abs () const
533     {
534       native_float r;
535       r.image = verbose_unop("abs ", image, do_abs(image));
536       return r;
537     }
538 
operator <(const native_float & b) const539   bool operator <  (const native_float &b) const
540     { return verbose_cmp(image, "<", b.image, image <  b.image); }
operator <=(const native_float & b) const541   bool operator <= (const native_float &b) const
542     { return verbose_cmp(image, "<=", b.image, image <= b.image); }
operator ==(const native_float & b) const543   bool operator == (const native_float &b) const
544     { return verbose_cmp(image, "==", b.image, image == b.image); }
operator !=(const native_float & b) const545   bool operator != (const native_float &b) const
546     { return verbose_cmp(image, "!=", b.image, image != b.image); }
operator >=(const native_float & b) const547   bool operator >= (const native_float &b) const
548     { return verbose_cmp(image, ">=", b.image, image >= b.image); }
operator >(const native_float & b) const549   bool operator >  (const native_float &b) const
550     { return verbose_cmp(image, ">", b.image, image > b.image); }
551 
552   const char * str () const;
553   const char * hex () const;
integer() const554   long integer () const
555     { return long(image); }
556   int exp () const;
557   void ldexp (int);
558 };
559 
560 template<typename T>
561 inline T
from_str(const char * s)562 native_float<T>::from_str (const char *s)
563 {
564   return strtold (s, NULL);
565 }
566 
567 template<>
568 inline float
from_str(const char * s)569 native_float<float>::from_str (const char *s)
570 {
571   return strtof (s, NULL);
572 }
573 
574 template<>
575 inline double
from_str(const char * s)576 native_float<double>::from_str (const char *s)
577 {
578   return strtod (s, NULL);
579 }
580 
581 template<typename T>
582 inline T
do_abs(T image)583 native_float<T>::do_abs (T image)
584 {
585   return fabsl (image);
586 }
587 
588 template<>
589 inline float
do_abs(float image)590 native_float<float>::do_abs (float image)
591 {
592   return fabsf (image);
593 }
594 
595 template<>
596 inline double
do_abs(double image)597 native_float<double>::do_abs (double image)
598 {
599   return fabs (image);
600 }
601 
602 template<typename T>
603 T
verbose_binop(T a,char symbol,T b,T r)604 native_float<T>::verbose_binop (T a, char symbol, T b, T r)
605 {
606   if (verbose)
607     {
608       const int digits = int(sizeof(T) * CHAR_BIT / 4) - 1;
609 #ifdef NO_LONG_DOUBLE
610       fprintf (stderr, "%6d: %.*a %c %.*a = %.*a\n", verbose_index++,
611 	       digits, (double)a, symbol,
612 	       digits, (double)b, digits, (double)r);
613 #else
614       fprintf (stderr, "%6d: %.*La %c %.*La = %.*La\n", verbose_index++,
615 	       digits, (long double)a, symbol,
616 	       digits, (long double)b, digits, (long double)r);
617 #endif
618     }
619   return r;
620 }
621 
622 template<typename T>
623 T
verbose_unop(const char * symbol,T a,T r)624 native_float<T>::verbose_unop (const char *symbol, T a, T r)
625 {
626   if (verbose)
627     {
628       const int digits = int(sizeof(T) * CHAR_BIT / 4) - 1;
629 #ifdef NO_LONG_DOUBLE
630       fprintf (stderr, "%6d: %s%.*a = %.*a\n", verbose_index++,
631 	       symbol, digits, (double)a, digits, (double)r);
632 #else
633       fprintf (stderr, "%6d: %s%.*La = %.*La\n", verbose_index++,
634 	       symbol, digits, (long double)a, digits, (long double)r);
635 #endif
636     }
637   return r;
638 }
639 
640 template<typename T>
641 bool
verbose_cmp(T a,const char * symbol,T b,bool r)642 native_float<T>::verbose_cmp (T a, const char *symbol, T b, bool r)
643 {
644   if (verbose)
645     {
646       const int digits = int(sizeof(T) * CHAR_BIT / 4) - 1;
647 #ifndef NO_LONG_DOUBLE
648       fprintf (stderr, "%6d: %.*a %s %.*a = %s\n", verbose_index++,
649 	       digits, (double)a, symbol,
650 	       digits, (double)b, (r ? "true" : "false"));
651 #else
652       fprintf (stderr, "%6d: %.*La %s %.*La = %s\n", verbose_index++,
653 	       digits, (long double)a, symbol,
654 	       digits, (long double)b, (r ? "true" : "false"));
655 #endif
656     }
657   return r;
658 }
659 
660 template<typename T>
661 const char *
str() const662 native_float<T>::str() const
663 {
664   char *buf = new char[50];
665   const int digits = int(sizeof(T) * CHAR_BIT * .30102999566398119521 + 1);
666 #ifndef NO_LONG_DOUBLE
667   sprintf (buf, "%.*e", digits - 1, (double) image);
668 #else
669   sprintf (buf, "%.*Le", digits - 1, (long double) image);
670 #endif
671   return buf;
672 }
673 
674 template<typename T>
675 const char *
hex() const676 native_float<T>::hex() const
677 {
678   char *buf = new char[50];
679   const int digits = int(sizeof(T) * CHAR_BIT / 4);
680 #ifndef NO_LONG_DOUBLE
681   sprintf (buf, "%.*a", digits - 1, (double) image);
682 #else
683   sprintf (buf, "%.*La", digits - 1, (long double) image);
684 #endif
685   return buf;
686 }
687 
688 template<typename T>
689 int
exp() const690 native_float<T>::exp() const
691 {
692   int e;
693   frexp (image, &e);
694   return e;
695 }
696 
697 template<typename T>
698 void
ldexp(int exp)699 native_float<T>::ldexp (int exp)
700 {
701   image = ldexpl (image, exp);
702 }
703 
704 template<>
705 void
ldexp(int exp)706 native_float<float>::ldexp (int exp)
707 {
708   image = ldexpf (image, exp);
709 }
710 
711 template<>
712 void
ldexp(int exp)713 native_float<double>::ldexp (int exp)
714 {
715   image = ::ldexp (image, exp);
716 }
717 
718 /* ====================================================================== */
719 /* Some libm routines that Paranoia expects to be available.  */
720 
721 template<typename FLOAT>
722 inline FLOAT
FABS(const FLOAT & f)723 FABS (const FLOAT &f)
724 {
725   return f.abs();
726 }
727 
728 template<typename FLOAT, typename RHS>
729 inline FLOAT
operator +(const FLOAT & a,const RHS & b)730 operator+ (const FLOAT &a, const RHS &b)
731 {
732   return FLOAT(a) += FLOAT(b);
733 }
734 
735 template<typename FLOAT, typename RHS>
736 inline FLOAT
operator -(const FLOAT & a,const RHS & b)737 operator- (const FLOAT &a, const RHS &b)
738 {
739   return FLOAT(a) -= FLOAT(b);
740 }
741 
742 template<typename FLOAT, typename RHS>
743 inline FLOAT
operator *(const FLOAT & a,const RHS & b)744 operator* (const FLOAT &a, const RHS &b)
745 {
746   return FLOAT(a) *= FLOAT(b);
747 }
748 
749 template<typename FLOAT, typename RHS>
750 inline FLOAT
operator /(const FLOAT & a,const RHS & b)751 operator/ (const FLOAT &a, const RHS &b)
752 {
753   return FLOAT(a) /= FLOAT(b);
754 }
755 
756 template<typename FLOAT>
757 FLOAT
FLOOR(const FLOAT & f)758 FLOOR (const FLOAT &f)
759 {
760   /* ??? This is only correct when F is representable as an integer.  */
761   long i = f.integer();
762   FLOAT r;
763 
764   r = i;
765   if (i < 0 && f != r)
766     r = i - 1;
767 
768   return r;
769 }
770 
771 template<typename FLOAT>
772 FLOAT
SQRT(const FLOAT & f)773 SQRT (const FLOAT &f)
774 {
775 #if 0
776   FLOAT zero = long(0);
777   FLOAT two = 2;
778   FLOAT one = 1;
779   FLOAT diff, diff2;
780   FLOAT z, t;
781 
782   if (f == zero)
783     return zero;
784   if (f < zero)
785     return zero / zero;
786   if (f == one)
787     return f;
788 
789   z = f;
790   z.ldexp (-f.exp() / 2);
791 
792   diff2 = FABS (z * z - f);
793   if (diff2 > zero)
794     while (1)
795       {
796 	t = (f / (two * z)) + (z / two);
797 	diff = FABS (t * t - f);
798 	if (diff >= diff2)
799 	  break;
800 	z = t;
801 	diff2 = diff;
802       }
803 
804   return z;
805 #elif defined(NO_LONG_DOUBLE)
806   double d;
807   char buf[64];
808 
809   d = strtod (f.hex(), NULL);
810   d = sqrt (d);
811   sprintf(buf, "%.35a", d);
812 
813   return FLOAT(buf);
814 #else
815   long double ld;
816   char buf[64];
817 
818   ld = strtold (f.hex(), NULL);
819   ld = sqrtl (ld);
820   sprintf(buf, "%.35La", ld);
821 
822   return FLOAT(buf);
823 #endif
824 }
825 
826 template<typename FLOAT>
827 FLOAT
LOG(FLOAT x)828 LOG (FLOAT x)
829 {
830 #if 0
831   FLOAT zero = long(0);
832   FLOAT one = 1;
833 
834   if (x <= zero)
835     return zero / zero;
836   if (x == one)
837     return zero;
838 
839   int exp = x.exp() - 1;
840   x.ldexp(-exp);
841 
842   FLOAT xm1 = x - one;
843   FLOAT y = xm1;
844   long n = 2;
845 
846   FLOAT sum = xm1;
847   while (1)
848     {
849       y *= xm1;
850       FLOAT term = y / FLOAT (n);
851       FLOAT next = sum + term;
852       if (next == sum)
853 	break;
854       sum = next;
855       if (++n == 1000)
856 	break;
857     }
858 
859   if (exp)
860     sum += FLOAT (exp) * FLOAT(".69314718055994530941");
861 
862   return sum;
863 #elif defined (NO_LONG_DOUBLE)
864   double d;
865   char buf[64];
866 
867   d = strtod (x.hex(), NULL);
868   d = log (d);
869   sprintf(buf, "%.35a", d);
870 
871   return FLOAT(buf);
872 #else
873   long double ld;
874   char buf[64];
875 
876   ld = strtold (x.hex(), NULL);
877   ld = logl (ld);
878   sprintf(buf, "%.35La", ld);
879 
880   return FLOAT(buf);
881 #endif
882 }
883 
884 template<typename FLOAT>
885 FLOAT
EXP(const FLOAT & x)886 EXP (const FLOAT &x)
887 {
888   /* Cheat.  */
889 #ifdef NO_LONG_DOUBLE
890   double d;
891   char buf[64];
892 
893   d = strtod (x.hex(), NULL);
894   d = exp (d);
895   sprintf(buf, "%.35a", d);
896 
897   return FLOAT(buf);
898 #else
899   long double ld;
900   char buf[64];
901 
902   ld = strtold (x.hex(), NULL);
903   ld = expl (ld);
904   sprintf(buf, "%.35La", ld);
905 
906   return FLOAT(buf);
907 #endif
908 }
909 
910 template<typename FLOAT>
911 FLOAT
POW(const FLOAT & base,const FLOAT & exp)912 POW (const FLOAT &base, const FLOAT &exp)
913 {
914   /* Cheat.  */
915 #ifdef NO_LONG_DOUBLE
916   double d1, d2;
917   char buf[64];
918 
919   d1 = strtod (base.hex(), NULL);
920   d2 = strtod (exp.hex(), NULL);
921   d1 = pow (d1, d2);
922   sprintf(buf, "%.35a", d1);
923 
924   return FLOAT(buf);
925 #else
926   long double ld1, ld2;
927   char buf[64];
928 
929   ld1 = strtold (base.hex(), NULL);
930   ld2 = strtold (exp.hex(), NULL);
931   ld1 = powl (ld1, ld2);
932   sprintf(buf, "%.35La", ld1);
933 
934   return FLOAT(buf);
935 #endif
936 }
937 
938 /* ====================================================================== */
939 /* Real Paranoia begins again here.  We wrap the thing in a template so
940    that we can instantiate it for each floating point type we care for.  */
941 
942 int NoTrials = 20;		/*Number of tests for commutativity. */
943 bool do_pause = false;
944 
945 enum Guard { No, Yes };
946 enum Rounding { Other, Rounded, Chopped };
947 enum Class { Failure, Serious, Defect, Flaw };
948 
949 template<typename FLOAT>
950 struct Paranoia
951 {
952   FLOAT Radix, BInvrse, RadixD2, BMinusU2;
953 
954   /* Small floating point constants.  */
955   FLOAT Zero;
956   FLOAT Half;
957   FLOAT One;
958   FLOAT Two;
959   FLOAT Three;
960   FLOAT Four;
961   FLOAT Five;
962   FLOAT Eight;
963   FLOAT Nine;
964   FLOAT TwentySeven;
965   FLOAT ThirtyTwo;
966   FLOAT TwoForty;
967   FLOAT MinusOne;
968   FLOAT OneAndHalf;
969 
970   /* Declarations of Variables.  */
971   int Indx;
972   char ch[8];
973   FLOAT AInvrse, A1;
974   FLOAT C, CInvrse;
975   FLOAT D, FourD;
976   FLOAT E0, E1, Exp2, E3, MinSqEr;
977   FLOAT SqEr, MaxSqEr, E9;
978   FLOAT Third;
979   FLOAT F6, F9;
980   FLOAT H, HInvrse;
981   int I;
982   FLOAT StickyBit, J;
983   FLOAT MyZero;
984   FLOAT Precision;
985   FLOAT Q, Q9;
986   FLOAT R, Random9;
987   FLOAT T, Underflow, S;
988   FLOAT OneUlp, UfThold, U1, U2;
989   FLOAT V, V0, V9;
990   FLOAT W;
991   FLOAT X, X1, X2, X8, Random1;
992   FLOAT Y, Y1, Y2, Random2;
993   FLOAT Z, PseudoZero, Z1, Z2, Z9;
994   int ErrCnt[4];
995   int Milestone;
996   int PageNo;
997   int M, N, N1;
998   Guard GMult, GDiv, GAddSub;
999   Rounding RMult, RDiv, RAddSub, RSqrt;
1000   int Break, Done, NotMonot, Monot, Anomaly, IEEE, SqRWrng, UfNGrad;
1001 
1002   /* Computed constants. */
1003   /*U1  gap below 1.0, i.e, 1.0-U1 is next number below 1.0 */
1004   /*U2  gap above 1.0, i.e, 1.0+U2 is next number above 1.0 */
1005 
1006   int main ();
1007 
1008   FLOAT Sign (FLOAT);
1009   FLOAT Random ();
1010   void Pause ();
1011   void BadCond (int, const char *);
1012   void SqXMinX (int);
1013   void TstCond (int, int, const char *);
1014   void notify (const char *);
1015   void IsYeqX ();
1016   void NewD ();
1017   void PrintIfNPositive ();
1018   void SR3750 ();
1019   void TstPtUf ();
1020 
1021   // Pretend we're bss.
ParanoiaParanoia1022   Paranoia() { memset(this, 0, sizeof (*this)); }
1023 };
1024 
1025 template<typename FLOAT>
1026 int
main()1027 Paranoia<FLOAT>::main()
1028 {
1029   /* First two assignments use integer right-hand sides. */
1030   Zero = long(0);
1031   One = long(1);
1032   Two = long(2);
1033   Three = long(3);
1034   Four = long(4);
1035   Five = long(5);
1036   Eight = long(8);
1037   Nine = long(9);
1038   TwentySeven = long(27);
1039   ThirtyTwo = long(32);
1040   TwoForty = long(240);
1041   MinusOne = long(-1);
1042   Half = "0x1p-1";
1043   OneAndHalf = "0x3p-1";
1044   ErrCnt[Failure] = 0;
1045   ErrCnt[Serious] = 0;
1046   ErrCnt[Defect] = 0;
1047   ErrCnt[Flaw] = 0;
1048   PageNo = 1;
1049 	/*=============================================*/
1050   Milestone = 7;
1051 	/*=============================================*/
1052   printf ("Program is now RUNNING tests on small integers:\n");
1053 
1054   TstCond (Failure, (Zero + Zero == Zero), "0+0 != 0");
1055   TstCond (Failure, (One - One == Zero), "1-1 != 0");
1056   TstCond (Failure, (One > Zero), "1 <= 0");
1057   TstCond (Failure, (One + One == Two), "1+1 != 2");
1058 
1059   Z = -Zero;
1060   if (Z != Zero)
1061     {
1062       ErrCnt[Failure] = ErrCnt[Failure] + 1;
1063       printf ("Comparison alleges that -0.0 is Non-zero!\n");
1064       U2 = "0.001";
1065       Radix = 1;
1066       TstPtUf ();
1067     }
1068 
1069   TstCond (Failure, (Three == Two + One), "3 != 2+1");
1070   TstCond (Failure, (Four == Three + One), "4 != 3+1");
1071   TstCond (Failure, (Four + Two * (-Two) == Zero), "4 + 2*(-2) != 0");
1072   TstCond (Failure, (Four - Three - One == Zero), "4-3-1 != 0");
1073 
1074   TstCond (Failure, (MinusOne == (Zero - One)), "-1 != 0-1");
1075   TstCond (Failure, (MinusOne + One == Zero), "-1+1 != 0");
1076   TstCond (Failure, (One + MinusOne == Zero), "1+(-1) != 0");
1077   TstCond (Failure, (MinusOne + FABS (One) == Zero), "-1+abs(1) != 0");
1078   TstCond (Failure, (MinusOne + MinusOne * MinusOne == Zero),
1079 	   "-1+(-1)*(-1) != 0");
1080 
1081   TstCond (Failure, Half + MinusOne + Half == Zero, "1/2 + (-1) + 1/2 != 0");
1082 
1083 	/*=============================================*/
1084   Milestone = 10;
1085 	/*=============================================*/
1086 
1087   TstCond (Failure, (Nine == Three * Three), "9 != 3*3");
1088   TstCond (Failure, (TwentySeven == Nine * Three), "27 != 9*3");
1089   TstCond (Failure, (Eight == Four + Four), "8 != 4+4");
1090   TstCond (Failure, (ThirtyTwo == Eight * Four), "32 != 8*4");
1091   TstCond (Failure, (ThirtyTwo - TwentySeven - Four - One == Zero),
1092 	   "32-27-4-1 != 0");
1093 
1094   TstCond (Failure, Five == Four + One, "5 != 4+1");
1095   TstCond (Failure, TwoForty == Four * Five * Three * Four, "240 != 4*5*3*4");
1096   TstCond (Failure, TwoForty / Three - Four * Four * Five == Zero,
1097 	   "240/3 - 4*4*5 != 0");
1098   TstCond (Failure, TwoForty / Four - Five * Three * Four == Zero,
1099 	   "240/4 - 5*3*4 != 0");
1100   TstCond (Failure, TwoForty / Five - Four * Three * Four == Zero,
1101 	   "240/5 - 4*3*4 != 0");
1102 
1103   if (ErrCnt[Failure] == 0)
1104     {
1105       printf ("-1, 0, 1/2, 1, 2, 3, 4, 5, 9, 27, 32 & 240 are O.K.\n");
1106       printf ("\n");
1107     }
1108   printf ("Searching for Radix and Precision.\n");
1109   W = One;
1110   do
1111     {
1112       W = W + W;
1113       Y = W + One;
1114       Z = Y - W;
1115       Y = Z - One;
1116     }
1117   while (MinusOne + FABS (Y) < Zero);
1118   /*.. now W is just big enough that |((W+1)-W)-1| >= 1 ... */
1119   Precision = Zero;
1120   Y = One;
1121   do
1122     {
1123       Radix = W + Y;
1124       Y = Y + Y;
1125       Radix = Radix - W;
1126     }
1127   while (Radix == Zero);
1128   if (Radix < Two)
1129     Radix = One;
1130   printf ("Radix = %s .\n", Radix.str());
1131   if (Radix != One)
1132     {
1133       W = One;
1134       do
1135 	{
1136 	  Precision = Precision + One;
1137 	  W = W * Radix;
1138 	  Y = W + One;
1139 	}
1140       while ((Y - W) == One);
1141     }
1142   /*... now W == Radix^Precision is barely too big to satisfy (W+1)-W == 1
1143      ... */
1144   U1 = One / W;
1145   U2 = Radix * U1;
1146   printf ("Closest relative separation found is U1 = %s .\n\n", U1.str());
1147   printf ("Recalculating radix and precision\n ");
1148 
1149   /*save old values */
1150   E0 = Radix;
1151   E1 = U1;
1152   E9 = U2;
1153   E3 = Precision;
1154 
1155   X = Four / Three;
1156   Third = X - One;
1157   F6 = Half - Third;
1158   X = F6 + F6;
1159   X = FABS (X - Third);
1160   if (X < U2)
1161     X = U2;
1162 
1163   /*... now X = (unknown no.) ulps of 1+... */
1164   do
1165     {
1166       U2 = X;
1167       Y = Half * U2 + ThirtyTwo * U2 * U2;
1168       Y = One + Y;
1169       X = Y - One;
1170     }
1171   while (!((U2 <= X) || (X <= Zero)));
1172 
1173   /*... now U2 == 1 ulp of 1 + ... */
1174   X = Two / Three;
1175   F6 = X - Half;
1176   Third = F6 + F6;
1177   X = Third - Half;
1178   X = FABS (X + F6);
1179   if (X < U1)
1180     X = U1;
1181 
1182   /*... now  X == (unknown no.) ulps of 1 -... */
1183   do
1184     {
1185       U1 = X;
1186       Y = Half * U1 + ThirtyTwo * U1 * U1;
1187       Y = Half - Y;
1188       X = Half + Y;
1189       Y = Half - X;
1190       X = Half + Y;
1191     }
1192   while (!((U1 <= X) || (X <= Zero)));
1193   /*... now U1 == 1 ulp of 1 - ... */
1194   if (U1 == E1)
1195     printf ("confirms closest relative separation U1 .\n");
1196   else
1197     printf ("gets better closest relative separation U1 = %s .\n", U1.str());
1198   W = One / U1;
1199   F9 = (Half - U1) + Half;
1200 
1201   Radix = FLOOR (FLOAT ("0.01") + U2 / U1);
1202   if (Radix == E0)
1203     printf ("Radix confirmed.\n");
1204   else
1205     printf ("MYSTERY: recalculated Radix = %s .\n", Radix.str());
1206   TstCond (Defect, Radix <= Eight + Eight,
1207 	   "Radix is too big: roundoff problems");
1208   TstCond (Flaw, (Radix == Two) || (Radix == 10)
1209 	   || (Radix == One), "Radix is not as good as 2 or 10");
1210 	/*=============================================*/
1211   Milestone = 20;
1212 	/*=============================================*/
1213   TstCond (Failure, F9 - Half < Half,
1214 	   "(1-U1)-1/2 < 1/2 is FALSE, prog. fails?");
1215   X = F9;
1216   I = 1;
1217   Y = X - Half;
1218   Z = Y - Half;
1219   TstCond (Failure, (X != One)
1220 	   || (Z == Zero), "Comparison is fuzzy,X=1 but X-1/2-1/2 != 0");
1221   X = One + U2;
1222   I = 0;
1223 	/*=============================================*/
1224   Milestone = 25;
1225 	/*=============================================*/
1226   /*... BMinusU2 = nextafter(Radix, 0) */
1227   BMinusU2 = Radix - One;
1228   BMinusU2 = (BMinusU2 - U2) + One;
1229   /* Purify Integers */
1230   if (Radix != One)
1231     {
1232       X = -TwoForty * LOG (U1) / LOG (Radix);
1233       Y = FLOOR (Half + X);
1234       if (FABS (X - Y) * Four < One)
1235 	X = Y;
1236       Precision = X / TwoForty;
1237       Y = FLOOR (Half + Precision);
1238       if (FABS (Precision - Y) * TwoForty < Half)
1239 	Precision = Y;
1240     }
1241   if ((Precision != FLOOR (Precision)) || (Radix == One))
1242     {
1243       printf ("Precision cannot be characterized by an Integer number\n");
1244       printf
1245 	("of significant digits but, by itself, this is a minor flaw.\n");
1246     }
1247   if (Radix == One)
1248     printf
1249       ("logarithmic encoding has precision characterized solely by U1.\n");
1250   else
1251     printf ("The number of significant digits of the Radix is %s .\n",
1252 	    Precision.str());
1253   TstCond (Serious, U2 * Nine * Nine * TwoForty < One,
1254 	   "Precision worse than 5 decimal figures  ");
1255 	/*=============================================*/
1256   Milestone = 30;
1257 	/*=============================================*/
1258   /* Test for extra-precise subexpressions */
1259   X = FABS (((Four / Three - One) - One / Four) * Three - One / Four);
1260   do
1261     {
1262       Z2 = X;
1263       X = (One + (Half * Z2 + ThirtyTwo * Z2 * Z2)) - One;
1264     }
1265   while (!((Z2 <= X) || (X <= Zero)));
1266   X = Y = Z = FABS ((Three / Four - Two / Three) * Three - One / Four);
1267   do
1268     {
1269       Z1 = Z;
1270       Z = (One / Two - ((One / Two - (Half * Z1 + ThirtyTwo * Z1 * Z1))
1271 			+ One / Two)) + One / Two;
1272     }
1273   while (!((Z1 <= Z) || (Z <= Zero)));
1274   do
1275     {
1276       do
1277 	{
1278 	  Y1 = Y;
1279 	  Y =
1280 	    (Half - ((Half - (Half * Y1 + ThirtyTwo * Y1 * Y1)) + Half)) +
1281 	    Half;
1282 	}
1283       while (!((Y1 <= Y) || (Y <= Zero)));
1284       X1 = X;
1285       X = ((Half * X1 + ThirtyTwo * X1 * X1) - F9) + F9;
1286     }
1287   while (!((X1 <= X) || (X <= Zero)));
1288   if ((X1 != Y1) || (X1 != Z1))
1289     {
1290       BadCond (Serious, "Disagreements among the values X1, Y1, Z1,\n");
1291       printf ("respectively  %s,  %s,  %s,\n", X1.str(), Y1.str(), Z1.str());
1292       printf ("are symptoms of inconsistencies introduced\n");
1293       printf ("by extra-precise evaluation of arithmetic subexpressions.\n");
1294       notify ("Possibly some part of this");
1295       if ((X1 == U1) || (Y1 == U1) || (Z1 == U1))
1296 	printf ("That feature is not tested further by this program.\n");
1297     }
1298   else
1299     {
1300       if ((Z1 != U1) || (Z2 != U2))
1301 	{
1302 	  if ((Z1 >= U1) || (Z2 >= U2))
1303 	    {
1304 	      BadCond (Failure, "");
1305 	      notify ("Precision");
1306 	      printf ("\tU1 = %s, Z1 - U1 = %s\n", U1.str(), (Z1 - U1).str());
1307 	      printf ("\tU2 = %s, Z2 - U2 = %s\n", U2.str(), (Z2 - U2).str());
1308 	    }
1309 	  else
1310 	    {
1311 	      if ((Z1 <= Zero) || (Z2 <= Zero))
1312 		{
1313 		  printf ("Because of unusual Radix = %s", Radix.str());
1314 		  printf (", or exact rational arithmetic a result\n");
1315 		  printf ("Z1 = %s, or Z2 = %s ", Z1.str(), Z2.str());
1316 		  notify ("of an\nextra-precision");
1317 		}
1318 	      if (Z1 != Z2 || Z1 > Zero)
1319 		{
1320 		  X = Z1 / U1;
1321 		  Y = Z2 / U2;
1322 		  if (Y > X)
1323 		    X = Y;
1324 		  Q = -LOG (X);
1325 		  printf ("Some subexpressions appear to be calculated "
1326 			  "extra precisely\n");
1327 		  printf ("with about %s extra B-digits, i.e.\n",
1328 			  (Q / LOG (Radix)).str());
1329 		  printf ("roughly %s extra significant decimals.\n",
1330 			  (Q / LOG (FLOAT (10))).str());
1331 		}
1332 	      printf
1333 		("That feature is not tested further by this program.\n");
1334 	    }
1335 	}
1336     }
1337   Pause ();
1338 	/*=============================================*/
1339   Milestone = 35;
1340 	/*=============================================*/
1341   if (Radix >= Two)
1342     {
1343       X = W / (Radix * Radix);
1344       Y = X + One;
1345       Z = Y - X;
1346       T = Z + U2;
1347       X = T - Z;
1348       TstCond (Failure, X == U2,
1349 	       "Subtraction is not normalized X=Y,X+Z != Y+Z!");
1350       if (X == U2)
1351 	printf ("Subtraction appears to be normalized, as it should be.");
1352     }
1353   printf ("\nChecking for guard digit in *, /, and -.\n");
1354   Y = F9 * One;
1355   Z = One * F9;
1356   X = F9 - Half;
1357   Y = (Y - Half) - X;
1358   Z = (Z - Half) - X;
1359   X = One + U2;
1360   T = X * Radix;
1361   R = Radix * X;
1362   X = T - Radix;
1363   X = X - Radix * U2;
1364   T = R - Radix;
1365   T = T - Radix * U2;
1366   X = X * (Radix - One);
1367   T = T * (Radix - One);
1368   if ((X == Zero) && (Y == Zero) && (Z == Zero) && (T == Zero))
1369     GMult = Yes;
1370   else
1371     {
1372       GMult = No;
1373       TstCond (Serious, false, "* lacks a Guard Digit, so 1*X != X");
1374     }
1375   Z = Radix * U2;
1376   X = One + Z;
1377   Y = FABS ((X + Z) - X * X) - U2;
1378   X = One - U2;
1379   Z = FABS ((X - U2) - X * X) - U1;
1380   TstCond (Failure, (Y <= Zero)
1381 	   && (Z <= Zero), "* gets too many final digits wrong.\n");
1382   Y = One - U2;
1383   X = One + U2;
1384   Z = One / Y;
1385   Y = Z - X;
1386   X = One / Three;
1387   Z = Three / Nine;
1388   X = X - Z;
1389   T = Nine / TwentySeven;
1390   Z = Z - T;
1391   TstCond (Defect, X == Zero && Y == Zero && Z == Zero,
1392 	   "Division lacks a Guard Digit, so error can exceed 1 ulp\n"
1393 	   "or  1/3  and  3/9  and  9/27 may disagree");
1394   Y = F9 / One;
1395   X = F9 - Half;
1396   Y = (Y - Half) - X;
1397   X = One + U2;
1398   T = X / One;
1399   X = T - X;
1400   if ((X == Zero) && (Y == Zero) && (Z == Zero))
1401     GDiv = Yes;
1402   else
1403     {
1404       GDiv = No;
1405       TstCond (Serious, false, "Division lacks a Guard Digit, so X/1 != X");
1406     }
1407   X = One / (One + U2);
1408   Y = X - Half - Half;
1409   TstCond (Serious, Y < Zero, "Computed value of 1/1.000..1 >= 1");
1410   X = One - U2;
1411   Y = One + Radix * U2;
1412   Z = X * Radix;
1413   T = Y * Radix;
1414   R = Z / Radix;
1415   StickyBit = T / Radix;
1416   X = R - X;
1417   Y = StickyBit - Y;
1418   TstCond (Failure, X == Zero && Y == Zero,
1419 	   "* and/or / gets too many last digits wrong");
1420   Y = One - U1;
1421   X = One - F9;
1422   Y = One - Y;
1423   T = Radix - U2;
1424   Z = Radix - BMinusU2;
1425   T = Radix - T;
1426   if ((X == U1) && (Y == U1) && (Z == U2) && (T == U2))
1427     GAddSub = Yes;
1428   else
1429     {
1430       GAddSub = No;
1431       TstCond (Serious, false,
1432 	       "- lacks Guard Digit, so cancellation is obscured");
1433     }
1434   if (F9 != One && F9 - One >= Zero)
1435     {
1436       BadCond (Serious, "comparison alleges  (1-U1) < 1  although\n");
1437       printf ("  subtraction yields  (1-U1) - 1 = 0 , thereby vitiating\n");
1438       printf ("  such precautions against division by zero as\n");
1439       printf ("  ...  if (X == 1.0) {.....} else {.../(X-1.0)...}\n");
1440     }
1441   if (GMult == Yes && GDiv == Yes && GAddSub == Yes)
1442     printf
1443       ("     *, /, and - appear to have guard digits, as they should.\n");
1444 	/*=============================================*/
1445   Milestone = 40;
1446 	/*=============================================*/
1447   Pause ();
1448   printf ("Checking rounding on multiply, divide and add/subtract.\n");
1449   RMult = Other;
1450   RDiv = Other;
1451   RAddSub = Other;
1452   RadixD2 = Radix / Two;
1453   A1 = Two;
1454   Done = false;
1455   do
1456     {
1457       AInvrse = Radix;
1458       do
1459 	{
1460 	  X = AInvrse;
1461 	  AInvrse = AInvrse / A1;
1462 	}
1463       while (!(FLOOR (AInvrse) != AInvrse));
1464       Done = (X == One) || (A1 > Three);
1465       if (!Done)
1466 	A1 = Nine + One;
1467     }
1468   while (!(Done));
1469   if (X == One)
1470     A1 = Radix;
1471   AInvrse = One / A1;
1472   X = A1;
1473   Y = AInvrse;
1474   Done = false;
1475   do
1476     {
1477       Z = X * Y - Half;
1478       TstCond (Failure, Z == Half, "X * (1/X) differs from 1");
1479       Done = X == Radix;
1480       X = Radix;
1481       Y = One / X;
1482     }
1483   while (!(Done));
1484   Y2 = One + U2;
1485   Y1 = One - U2;
1486   X = OneAndHalf - U2;
1487   Y = OneAndHalf + U2;
1488   Z = (X - U2) * Y2;
1489   T = Y * Y1;
1490   Z = Z - X;
1491   T = T - X;
1492   X = X * Y2;
1493   Y = (Y + U2) * Y1;
1494   X = X - OneAndHalf;
1495   Y = Y - OneAndHalf;
1496   if ((X == Zero) && (Y == Zero) && (Z == Zero) && (T <= Zero))
1497     {
1498       X = (OneAndHalf + U2) * Y2;
1499       Y = OneAndHalf - U2 - U2;
1500       Z = OneAndHalf + U2 + U2;
1501       T = (OneAndHalf - U2) * Y1;
1502       X = X - (Z + U2);
1503       StickyBit = Y * Y1;
1504       S = Z * Y2;
1505       T = T - Y;
1506       Y = (U2 - Y) + StickyBit;
1507       Z = S - (Z + U2 + U2);
1508       StickyBit = (Y2 + U2) * Y1;
1509       Y1 = Y2 * Y1;
1510       StickyBit = StickyBit - Y2;
1511       Y1 = Y1 - Half;
1512       if ((X == Zero) && (Y == Zero) && (Z == Zero) && (T == Zero)
1513 	  && (StickyBit == Zero) && (Y1 == Half))
1514 	{
1515 	  RMult = Rounded;
1516 	  printf ("Multiplication appears to round correctly.\n");
1517 	}
1518       else if ((X + U2 == Zero) && (Y < Zero) && (Z + U2 == Zero)
1519 	       && (T < Zero) && (StickyBit + U2 == Zero) && (Y1 < Half))
1520 	{
1521 	  RMult = Chopped;
1522 	  printf ("Multiplication appears to chop.\n");
1523 	}
1524       else
1525 	printf ("* is neither chopped nor correctly rounded.\n");
1526       if ((RMult == Rounded) && (GMult == No))
1527 	notify ("Multiplication");
1528     }
1529   else
1530     printf ("* is neither chopped nor correctly rounded.\n");
1531 	/*=============================================*/
1532   Milestone = 45;
1533 	/*=============================================*/
1534   Y2 = One + U2;
1535   Y1 = One - U2;
1536   Z = OneAndHalf + U2 + U2;
1537   X = Z / Y2;
1538   T = OneAndHalf - U2 - U2;
1539   Y = (T - U2) / Y1;
1540   Z = (Z + U2) / Y2;
1541   X = X - OneAndHalf;
1542   Y = Y - T;
1543   T = T / Y1;
1544   Z = Z - (OneAndHalf + U2);
1545   T = (U2 - OneAndHalf) + T;
1546   if (!((X > Zero) || (Y > Zero) || (Z > Zero) || (T > Zero)))
1547     {
1548       X = OneAndHalf / Y2;
1549       Y = OneAndHalf - U2;
1550       Z = OneAndHalf + U2;
1551       X = X - Y;
1552       T = OneAndHalf / Y1;
1553       Y = Y / Y1;
1554       T = T - (Z + U2);
1555       Y = Y - Z;
1556       Z = Z / Y2;
1557       Y1 = (Y2 + U2) / Y2;
1558       Z = Z - OneAndHalf;
1559       Y2 = Y1 - Y2;
1560       Y1 = (F9 - U1) / F9;
1561       if ((X == Zero) && (Y == Zero) && (Z == Zero) && (T == Zero)
1562 	  && (Y2 == Zero) && (Y2 == Zero) && (Y1 - Half == F9 - Half))
1563 	{
1564 	  RDiv = Rounded;
1565 	  printf ("Division appears to round correctly.\n");
1566 	  if (GDiv == No)
1567 	    notify ("Division");
1568 	}
1569       else if ((X < Zero) && (Y < Zero) && (Z < Zero) && (T < Zero)
1570 	       && (Y2 < Zero) && (Y1 - Half < F9 - Half))
1571 	{
1572 	  RDiv = Chopped;
1573 	  printf ("Division appears to chop.\n");
1574 	}
1575     }
1576   if (RDiv == Other)
1577     printf ("/ is neither chopped nor correctly rounded.\n");
1578   BInvrse = One / Radix;
1579   TstCond (Failure, (BInvrse * Radix - Half == Half),
1580 	   "Radix * ( 1 / Radix ) differs from 1");
1581 	/*=============================================*/
1582   Milestone = 50;
1583 	/*=============================================*/
1584   TstCond (Failure, ((F9 + U1) - Half == Half)
1585 	   && ((BMinusU2 + U2) - One == Radix - One),
1586 	   "Incomplete carry-propagation in Addition");
1587   X = One - U1 * U1;
1588   Y = One + U2 * (One - U2);
1589   Z = F9 - Half;
1590   X = (X - Half) - Z;
1591   Y = Y - One;
1592   if ((X == Zero) && (Y == Zero))
1593     {
1594       RAddSub = Chopped;
1595       printf ("Add/Subtract appears to be chopped.\n");
1596     }
1597   if (GAddSub == Yes)
1598     {
1599       X = (Half + U2) * U2;
1600       Y = (Half - U2) * U2;
1601       X = One + X;
1602       Y = One + Y;
1603       X = (One + U2) - X;
1604       Y = One - Y;
1605       if ((X == Zero) && (Y == Zero))
1606 	{
1607 	  X = (Half + U2) * U1;
1608 	  Y = (Half - U2) * U1;
1609 	  X = One - X;
1610 	  Y = One - Y;
1611 	  X = F9 - X;
1612 	  Y = One - Y;
1613 	  if ((X == Zero) && (Y == Zero))
1614 	    {
1615 	      RAddSub = Rounded;
1616 	      printf ("Addition/Subtraction appears to round correctly.\n");
1617 	      if (GAddSub == No)
1618 		notify ("Add/Subtract");
1619 	    }
1620 	  else
1621 	    printf ("Addition/Subtraction neither rounds nor chops.\n");
1622 	}
1623       else
1624 	printf ("Addition/Subtraction neither rounds nor chops.\n");
1625     }
1626   else
1627     printf ("Addition/Subtraction neither rounds nor chops.\n");
1628   S = One;
1629   X = One + Half * (One + Half);
1630   Y = (One + U2) * Half;
1631   Z = X - Y;
1632   T = Y - X;
1633   StickyBit = Z + T;
1634   if (StickyBit != Zero)
1635     {
1636       S = Zero;
1637       BadCond (Flaw, "(X - Y) + (Y - X) is non zero!\n");
1638     }
1639   StickyBit = Zero;
1640   if ((GMult == Yes) && (GDiv == Yes) && (GAddSub == Yes)
1641       && (RMult == Rounded) && (RDiv == Rounded)
1642       && (RAddSub == Rounded) && (FLOOR (RadixD2) == RadixD2))
1643     {
1644       printf ("Checking for sticky bit.\n");
1645       X = (Half + U1) * U2;
1646       Y = Half * U2;
1647       Z = One + Y;
1648       T = One + X;
1649       if ((Z - One <= Zero) && (T - One >= U2))
1650 	{
1651 	  Z = T + Y;
1652 	  Y = Z - X;
1653 	  if ((Z - T >= U2) && (Y - T == Zero))
1654 	    {
1655 	      X = (Half + U1) * U1;
1656 	      Y = Half * U1;
1657 	      Z = One - Y;
1658 	      T = One - X;
1659 	      if ((Z - One == Zero) && (T - F9 == Zero))
1660 		{
1661 		  Z = (Half - U1) * U1;
1662 		  T = F9 - Z;
1663 		  Q = F9 - Y;
1664 		  if ((T - F9 == Zero) && (F9 - U1 - Q == Zero))
1665 		    {
1666 		      Z = (One + U2) * OneAndHalf;
1667 		      T = (OneAndHalf + U2) - Z + U2;
1668 		      X = One + Half / Radix;
1669 		      Y = One + Radix * U2;
1670 		      Z = X * Y;
1671 		      if (T == Zero && X + Radix * U2 - Z == Zero)
1672 			{
1673 			  if (Radix != Two)
1674 			    {
1675 			      X = Two + U2;
1676 			      Y = X / Two;
1677 			      if ((Y - One == Zero))
1678 				StickyBit = S;
1679 			    }
1680 			  else
1681 			    StickyBit = S;
1682 			}
1683 		    }
1684 		}
1685 	    }
1686 	}
1687     }
1688   if (StickyBit == One)
1689     printf ("Sticky bit apparently used correctly.\n");
1690   else
1691     printf ("Sticky bit used incorrectly or not at all.\n");
1692   TstCond (Flaw, !(GMult == No || GDiv == No || GAddSub == No ||
1693 		   RMult == Other || RDiv == Other || RAddSub == Other),
1694 	   "lack(s) of guard digits or failure(s) to correctly round or chop\n\
1695 (noted above) count as one flaw in the final tally below");
1696 	/*=============================================*/
1697   Milestone = 60;
1698 	/*=============================================*/
1699   printf ("\n");
1700   printf ("Does Multiplication commute?  ");
1701   printf ("Testing on %d random pairs.\n", NoTrials);
1702   Random9 = SQRT (FLOAT (3));
1703   Random1 = Third;
1704   I = 1;
1705   do
1706     {
1707       X = Random ();
1708       Y = Random ();
1709       Z9 = Y * X;
1710       Z = X * Y;
1711       Z9 = Z - Z9;
1712       I = I + 1;
1713     }
1714   while (!((I > NoTrials) || (Z9 != Zero)));
1715   if (I == NoTrials)
1716     {
1717       Random1 = One + Half / Three;
1718       Random2 = (U2 + U1) + One;
1719       Z = Random1 * Random2;
1720       Y = Random2 * Random1;
1721       Z9 = (One + Half / Three) * ((U2 + U1) + One) - (One + Half /
1722 						       Three) * ((U2 + U1) +
1723 								 One);
1724     }
1725   if (!((I == NoTrials) || (Z9 == Zero)))
1726     BadCond (Defect, "X * Y == Y * X trial fails.\n");
1727   else
1728     printf ("     No failures found in %d integer pairs.\n", NoTrials);
1729 	/*=============================================*/
1730   Milestone = 70;
1731 	/*=============================================*/
1732   printf ("\nRunning test of square root(x).\n");
1733   TstCond (Failure, (Zero == SQRT (Zero))
1734 	   && (-Zero == SQRT (-Zero))
1735 	   && (One == SQRT (One)), "Square root of 0.0, -0.0 or 1.0 wrong");
1736   MinSqEr = Zero;
1737   MaxSqEr = Zero;
1738   J = Zero;
1739   X = Radix;
1740   OneUlp = U2;
1741   SqXMinX (Serious);
1742   X = BInvrse;
1743   OneUlp = BInvrse * U1;
1744   SqXMinX (Serious);
1745   X = U1;
1746   OneUlp = U1 * U1;
1747   SqXMinX (Serious);
1748   if (J != Zero)
1749     Pause ();
1750   printf ("Testing if sqrt(X * X) == X for %d Integers X.\n", NoTrials);
1751   J = Zero;
1752   X = Two;
1753   Y = Radix;
1754   if ((Radix != One))
1755     do
1756       {
1757 	X = Y;
1758 	Y = Radix * Y;
1759       }
1760     while (!((Y - X >= NoTrials)));
1761   OneUlp = X * U2;
1762   I = 1;
1763   while (I <= NoTrials)
1764     {
1765       X = X + One;
1766       SqXMinX (Defect);
1767       if (J > Zero)
1768 	break;
1769       I = I + 1;
1770     }
1771   printf ("Test for sqrt monotonicity.\n");
1772   I = -1;
1773   X = BMinusU2;
1774   Y = Radix;
1775   Z = Radix + Radix * U2;
1776   NotMonot = false;
1777   Monot = false;
1778   while (!(NotMonot || Monot))
1779     {
1780       I = I + 1;
1781       X = SQRT (X);
1782       Q = SQRT (Y);
1783       Z = SQRT (Z);
1784       if ((X > Q) || (Q > Z))
1785 	NotMonot = true;
1786       else
1787 	{
1788 	  Q = FLOOR (Q + Half);
1789 	  if (!(I > 0 || Radix == Q * Q))
1790 	    Monot = true;
1791 	  else if (I > 0)
1792 	    {
1793 	      if (I > 1)
1794 		Monot = true;
1795 	      else
1796 		{
1797 		  Y = Y * BInvrse;
1798 		  X = Y - U1;
1799 		  Z = Y + U1;
1800 		}
1801 	    }
1802 	  else
1803 	    {
1804 	      Y = Q;
1805 	      X = Y - U2;
1806 	      Z = Y + U2;
1807 	    }
1808 	}
1809     }
1810   if (Monot)
1811     printf ("sqrt has passed a test for Monotonicity.\n");
1812   else
1813     {
1814       BadCond (Defect, "");
1815       printf ("sqrt(X) is non-monotonic for X near %s .\n", Y.str());
1816     }
1817 	/*=============================================*/
1818   Milestone = 110;
1819 	/*=============================================*/
1820   printf ("Seeking Underflow thresholds UfThold and E0.\n");
1821   D = U1;
1822   if (Precision != FLOOR (Precision))
1823     {
1824       D = BInvrse;
1825       X = Precision;
1826       do
1827 	{
1828 	  D = D * BInvrse;
1829 	  X = X - One;
1830 	}
1831       while (X > Zero);
1832     }
1833   Y = One;
1834   Z = D;
1835   /* ... D is power of 1/Radix < 1. */
1836   do
1837     {
1838       C = Y;
1839       Y = Z;
1840       Z = Y * Y;
1841     }
1842   while ((Y > Z) && (Z + Z > Z));
1843   Y = C;
1844   Z = Y * D;
1845   do
1846     {
1847       C = Y;
1848       Y = Z;
1849       Z = Y * D;
1850     }
1851   while ((Y > Z) && (Z + Z > Z));
1852   if (Radix < Two)
1853     HInvrse = Two;
1854   else
1855     HInvrse = Radix;
1856   H = One / HInvrse;
1857   /* ... 1/HInvrse == H == Min(1/Radix, 1/2) */
1858   CInvrse = One / C;
1859   E0 = C;
1860   Z = E0 * H;
1861   /* ...1/Radix^(BIG Integer) << 1 << CInvrse == 1/C */
1862   do
1863     {
1864       Y = E0;
1865       E0 = Z;
1866       Z = E0 * H;
1867     }
1868   while ((E0 > Z) && (Z + Z > Z));
1869   UfThold = E0;
1870   E1 = Zero;
1871   Q = Zero;
1872   E9 = U2;
1873   S = One + E9;
1874   D = C * S;
1875   if (D <= C)
1876     {
1877       E9 = Radix * U2;
1878       S = One + E9;
1879       D = C * S;
1880       if (D <= C)
1881 	{
1882 	  BadCond (Failure,
1883 		   "multiplication gets too many last digits wrong.\n");
1884 	  Underflow = E0;
1885 	  Y1 = Zero;
1886 	  PseudoZero = Z;
1887 	  Pause ();
1888 	}
1889     }
1890   else
1891     {
1892       Underflow = D;
1893       PseudoZero = Underflow * H;
1894       UfThold = Zero;
1895       do
1896 	{
1897 	  Y1 = Underflow;
1898 	  Underflow = PseudoZero;
1899 	  if (E1 + E1 <= E1)
1900 	    {
1901 	      Y2 = Underflow * HInvrse;
1902 	      E1 = FABS (Y1 - Y2);
1903 	      Q = Y1;
1904 	      if ((UfThold == Zero) && (Y1 != Y2))
1905 		UfThold = Y1;
1906 	    }
1907 	  PseudoZero = PseudoZero * H;
1908 	}
1909       while ((Underflow > PseudoZero)
1910 	     && (PseudoZero + PseudoZero > PseudoZero));
1911     }
1912   /* Comment line 4530 .. 4560 */
1913   if (PseudoZero != Zero)
1914     {
1915       printf ("\n");
1916       Z = PseudoZero;
1917       /* ... Test PseudoZero for "phoney- zero" violates */
1918       /* ... PseudoZero < Underflow or PseudoZero < PseudoZero + PseudoZero
1919          ... */
1920       if (PseudoZero <= Zero)
1921 	{
1922 	  BadCond (Failure, "Positive expressions can underflow to an\n");
1923 	  printf ("allegedly negative value\n");
1924 	  printf ("PseudoZero that prints out as: %s .\n", PseudoZero.str());
1925 	  X = -PseudoZero;
1926 	  if (X <= Zero)
1927 	    {
1928 	      printf ("But -PseudoZero, which should be\n");
1929 	      printf ("positive, isn't; it prints out as  %s .\n", X.str());
1930 	    }
1931 	}
1932       else
1933 	{
1934 	  BadCond (Flaw, "Underflow can stick at an allegedly positive\n");
1935 	  printf ("value PseudoZero that prints out as %s .\n",
1936 		  PseudoZero.str());
1937 	}
1938       TstPtUf ();
1939     }
1940 	/*=============================================*/
1941   Milestone = 120;
1942 	/*=============================================*/
1943   if (CInvrse * Y > CInvrse * Y1)
1944     {
1945       S = H * S;
1946       E0 = Underflow;
1947     }
1948   if (!((E1 == Zero) || (E1 == E0)))
1949     {
1950       BadCond (Defect, "");
1951       if (E1 < E0)
1952 	{
1953 	  printf ("Products underflow at a higher");
1954 	  printf (" threshold than differences.\n");
1955 	  if (PseudoZero == Zero)
1956 	    E0 = E1;
1957 	}
1958       else
1959 	{
1960 	  printf ("Difference underflows at a higher");
1961 	  printf (" threshold than products.\n");
1962 	}
1963     }
1964   printf ("Smallest strictly positive number found is E0 = %s .\n", E0.str());
1965   Z = E0;
1966   TstPtUf ();
1967   Underflow = E0;
1968   if (N == 1)
1969     Underflow = Y;
1970   I = 4;
1971   if (E1 == Zero)
1972     I = 3;
1973   if (UfThold == Zero)
1974     I = I - 2;
1975   UfNGrad = true;
1976   switch (I)
1977     {
1978     case 1:
1979       UfThold = Underflow;
1980       if ((CInvrse * Q) != ((CInvrse * Y) * S))
1981 	{
1982 	  UfThold = Y;
1983 	  BadCond (Failure, "Either accuracy deteriorates as numbers\n");
1984 	  printf ("approach a threshold = %s\n", UfThold.str());
1985 	  printf (" coming down from %s\n", C.str());
1986 	  printf
1987 	    (" or else multiplication gets too many last digits wrong.\n");
1988 	}
1989       Pause ();
1990       break;
1991 
1992     case 2:
1993       BadCond (Failure,
1994 	       "Underflow confuses Comparison, which alleges that\n");
1995       printf ("Q == Y while denying that |Q - Y| == 0; these values\n");
1996       printf ("print out as Q = %s, Y = %s .\n", Q.str(), Y2.str());
1997       printf ("|Q - Y| = %s .\n", FABS (Q - Y2).str());
1998       UfThold = Q;
1999       break;
2000 
2001     case 3:
2002       X = X;
2003       break;
2004 
2005     case 4:
2006       if ((Q == UfThold) && (E1 == E0) && (FABS (UfThold - E1 / E9) <= E1))
2007 	{
2008 	  UfNGrad = false;
2009 	  printf ("Underflow is gradual; it incurs Absolute Error =\n");
2010 	  printf ("(roundoff in UfThold) < E0.\n");
2011 	  Y = E0 * CInvrse;
2012 	  Y = Y * (OneAndHalf + U2);
2013 	  X = CInvrse * (One + U2);
2014 	  Y = Y / X;
2015 	  IEEE = (Y == E0);
2016 	}
2017     }
2018   if (UfNGrad)
2019     {
2020       printf ("\n");
2021       if (setjmp (ovfl_buf))
2022 	{
2023 	  printf ("Underflow / UfThold failed!\n");
2024 	  R = H + H;
2025 	}
2026       else
2027 	R = SQRT (Underflow / UfThold);
2028       if (R <= H)
2029 	{
2030 	  Z = R * UfThold;
2031 	  X = Z * (One + R * H * (One + H));
2032 	}
2033       else
2034 	{
2035 	  Z = UfThold;
2036 	  X = Z * (One + H * H * (One + H));
2037 	}
2038       if (!((X == Z) || (X - Z != Zero)))
2039 	{
2040 	  BadCond (Flaw, "");
2041 	  printf ("X = %s\n\tis not equal to Z = %s .\n", X.str(), Z.str());
2042 	  Z9 = X - Z;
2043 	  printf ("yet X - Z yields %s .\n", Z9.str());
2044 	  printf ("    Should this NOT signal Underflow, ");
2045 	  printf ("this is a SERIOUS DEFECT\nthat causes ");
2046 	  printf ("confusion when innocent statements like\n");;
2047 	  printf ("    if (X == Z)  ...  else");
2048 	  printf ("  ... (f(X) - f(Z)) / (X - Z) ...\n");
2049 	  printf ("encounter Division by Zero although actually\n");
2050 	  if (setjmp (ovfl_buf))
2051 	    printf ("X / Z fails!\n");
2052 	  else
2053 	    printf ("X / Z = 1 + %s .\n", ((X / Z - Half) - Half).str());
2054 	}
2055     }
2056   printf ("The Underflow threshold is %s, below which\n", UfThold.str());
2057   printf ("calculation may suffer larger Relative error than ");
2058   printf ("merely roundoff.\n");
2059   Y2 = U1 * U1;
2060   Y = Y2 * Y2;
2061   Y2 = Y * U1;
2062   if (Y2 <= UfThold)
2063     {
2064       if (Y > E0)
2065 	{
2066 	  BadCond (Defect, "");
2067 	  I = 5;
2068 	}
2069       else
2070 	{
2071 	  BadCond (Serious, "");
2072 	  I = 4;
2073 	}
2074       printf ("Range is too narrow; U1^%d Underflows.\n", I);
2075     }
2076 	/*=============================================*/
2077   Milestone = 130;
2078 	/*=============================================*/
2079   Y = -FLOOR (Half - TwoForty * LOG (UfThold) / LOG (HInvrse)) / TwoForty;
2080   Y2 = Y + Y;
2081   printf ("Since underflow occurs below the threshold\n");
2082   printf ("UfThold = (%s) ^ (%s)\nonly underflow ", HInvrse.str(), Y.str());
2083   printf ("should afflict the expression\n\t(%s) ^ (%s);\n",
2084 	  HInvrse.str(), Y2.str());
2085   printf ("actually calculating yields:");
2086   if (setjmp (ovfl_buf))
2087     {
2088       BadCond (Serious, "trap on underflow.\n");
2089     }
2090   else
2091     {
2092       V9 = POW (HInvrse, Y2);
2093       printf (" %s .\n", V9.str());
2094       if (!((V9 >= Zero) && (V9 <= (Radix + Radix + E9) * UfThold)))
2095 	{
2096 	  BadCond (Serious, "this is not between 0 and underflow\n");
2097 	  printf ("   threshold = %s .\n", UfThold.str());
2098 	}
2099       else if (!(V9 > UfThold * (One + E9)))
2100 	printf ("This computed value is O.K.\n");
2101       else
2102 	{
2103 	  BadCond (Defect, "this is not between 0 and underflow\n");
2104 	  printf ("   threshold = %s .\n", UfThold.str());
2105 	}
2106     }
2107 	/*=============================================*/
2108   Milestone = 160;
2109 	/*=============================================*/
2110   Pause ();
2111   printf ("Searching for Overflow threshold:\n");
2112   printf ("This may generate an error.\n");
2113   Y = -CInvrse;
2114   V9 = HInvrse * Y;
2115   if (setjmp (ovfl_buf))
2116     {
2117       I = 0;
2118       V9 = Y;
2119       goto overflow;
2120     }
2121   do
2122     {
2123       V = Y;
2124       Y = V9;
2125       V9 = HInvrse * Y;
2126     }
2127   while (V9 < Y);
2128   I = 1;
2129 overflow:
2130   Z = V9;
2131   printf ("Can `Z = -Y' overflow?\n");
2132   printf ("Trying it on Y = %s .\n", Y.str());
2133   V9 = -Y;
2134   V0 = V9;
2135   if (V - Y == V + V0)
2136     printf ("Seems O.K.\n");
2137   else
2138     {
2139       printf ("finds a ");
2140       BadCond (Flaw, "-(-Y) differs from Y.\n");
2141     }
2142   if (Z != Y)
2143     {
2144       BadCond (Serious, "");
2145       printf ("overflow past %s\n\tshrinks to %s .\n", Y.str(), Z.str());
2146     }
2147   if (I)
2148     {
2149       Y = V * (HInvrse * U2 - HInvrse);
2150       Z = Y + ((One - HInvrse) * U2) * V;
2151       if (Z < V0)
2152 	Y = Z;
2153       if (Y < V0)
2154 	V = Y;
2155       if (V0 - V < V0)
2156 	V = V0;
2157     }
2158   else
2159     {
2160       V = Y * (HInvrse * U2 - HInvrse);
2161       V = V + ((One - HInvrse) * U2) * Y;
2162     }
2163   printf ("Overflow threshold is V  = %s .\n", V.str());
2164   if (I)
2165     printf ("Overflow saturates at V0 = %s .\n", V0.str());
2166   else
2167     printf ("There is no saturation value because "
2168 	    "the system traps on overflow.\n");
2169   V9 = V * One;
2170   printf ("No Overflow should be signaled for V * 1 = %s\n", V9.str());
2171   V9 = V / One;
2172   printf ("                           nor for V / 1 = %s.\n", V9.str());
2173   printf ("Any overflow signal separating this * from the one\n");
2174   printf ("above is a DEFECT.\n");
2175 	/*=============================================*/
2176   Milestone = 170;
2177 	/*=============================================*/
2178   if (!(-V < V && -V0 < V0 && -UfThold < V && UfThold < V))
2179     {
2180       BadCond (Failure, "Comparisons involving ");
2181       printf ("+-%s, +-%s\nand +-%s are confused by Overflow.",
2182 	      V.str(), V0.str(), UfThold.str());
2183     }
2184 	/*=============================================*/
2185   Milestone = 175;
2186 	/*=============================================*/
2187   printf ("\n");
2188   for (Indx = 1; Indx <= 3; ++Indx)
2189     {
2190       switch (Indx)
2191 	{
2192 	case 1:
2193 	  Z = UfThold;
2194 	  break;
2195 	case 2:
2196 	  Z = E0;
2197 	  break;
2198 	case 3:
2199 	  Z = PseudoZero;
2200 	  break;
2201 	}
2202       if (Z != Zero)
2203 	{
2204 	  V9 = SQRT (Z);
2205 	  Y = V9 * V9;
2206 	  if (Y / (One - Radix * E9) < Z || Y > (One + Radix * E9) * Z)
2207 	    {			/* dgh: + E9 --> * E9 */
2208 	      if (V9 > U1)
2209 		BadCond (Serious, "");
2210 	      else
2211 		BadCond (Defect, "");
2212 	      printf ("Comparison alleges that what prints as Z = %s\n",
2213 		      Z.str());
2214 	      printf (" is too far from sqrt(Z) ^ 2 = %s .\n", Y.str());
2215 	    }
2216 	}
2217     }
2218 	/*=============================================*/
2219   Milestone = 180;
2220 	/*=============================================*/
2221   for (Indx = 1; Indx <= 2; ++Indx)
2222     {
2223       if (Indx == 1)
2224 	Z = V;
2225       else
2226 	Z = V0;
2227       V9 = SQRT (Z);
2228       X = (One - Radix * E9) * V9;
2229       V9 = V9 * X;
2230       if (((V9 < (One - Two * Radix * E9) * Z) || (V9 > Z)))
2231 	{
2232 	  Y = V9;
2233 	  if (X < W)
2234 	    BadCond (Serious, "");
2235 	  else
2236 	    BadCond (Defect, "");
2237 	  printf ("Comparison alleges that Z = %s\n", Z.str());
2238 	  printf (" is too far from sqrt(Z) ^ 2 (%s) .\n", Y.str());
2239 	}
2240     }
2241 	/*=============================================*/
2242   Milestone = 190;
2243 	/*=============================================*/
2244   Pause ();
2245   X = UfThold * V;
2246   Y = Radix * Radix;
2247   if (X * Y < One || X > Y)
2248     {
2249       if (X * Y < U1 || X > Y / U1)
2250 	BadCond (Defect, "Badly");
2251       else
2252 	BadCond (Flaw, "");
2253 
2254       printf (" unbalanced range; UfThold * V = %s\n\t%s\n",
2255 	      X.str(), "is too far from 1.\n");
2256     }
2257 	/*=============================================*/
2258   Milestone = 200;
2259 	/*=============================================*/
2260   for (Indx = 1; Indx <= 5; ++Indx)
2261     {
2262       X = F9;
2263       switch (Indx)
2264 	{
2265 	case 2:
2266 	  X = One + U2;
2267 	  break;
2268 	case 3:
2269 	  X = V;
2270 	  break;
2271 	case 4:
2272 	  X = UfThold;
2273 	  break;
2274 	case 5:
2275 	  X = Radix;
2276 	}
2277       Y = X;
2278       if (setjmp (ovfl_buf))
2279 	printf ("  X / X  traps when X = %s\n", X.str());
2280       else
2281 	{
2282 	  V9 = (Y / X - Half) - Half;
2283 	  if (V9 == Zero)
2284 	    continue;
2285 	  if (V9 == -U1 && Indx < 5)
2286 	    BadCond (Flaw, "");
2287 	  else
2288 	    BadCond (Serious, "");
2289 	  printf ("  X / X differs from 1 when X = %s\n", X.str());
2290 	  printf ("  instead, X / X - 1/2 - 1/2 = %s .\n", V9.str());
2291 	}
2292     }
2293 	/*=============================================*/
2294   Milestone = 210;
2295 	/*=============================================*/
2296   MyZero = Zero;
2297   printf ("\n");
2298   printf ("What message and/or values does Division by Zero produce?\n");
2299   printf ("    Trying to compute 1 / 0 produces ...");
2300   if (!setjmp (ovfl_buf))
2301     printf ("  %s .\n", (One / MyZero).str());
2302   printf ("\n    Trying to compute 0 / 0 produces ...");
2303   if (!setjmp (ovfl_buf))
2304     printf ("  %s .\n", (Zero / MyZero).str());
2305 	/*=============================================*/
2306   Milestone = 220;
2307 	/*=============================================*/
2308   Pause ();
2309   printf ("\n");
2310   {
2311     static const char *msg[] = {
2312       "FAILUREs  encountered =",
2313       "SERIOUS DEFECTs  discovered =",
2314       "DEFECTs  discovered =",
2315       "FLAWs  discovered ="
2316     };
2317     int i;
2318     for (i = 0; i < 4; i++)
2319       if (ErrCnt[i])
2320 	printf ("The number of  %-29s %d.\n", msg[i], ErrCnt[i]);
2321   }
2322   printf ("\n");
2323   if ((ErrCnt[Failure] + ErrCnt[Serious] + ErrCnt[Defect] + ErrCnt[Flaw]) > 0)
2324     {
2325       if ((ErrCnt[Failure] + ErrCnt[Serious] + ErrCnt[Defect] == 0)
2326 	  && (ErrCnt[Flaw] > 0))
2327 	{
2328 	  printf ("The arithmetic diagnosed seems ");
2329 	  printf ("Satisfactory though flawed.\n");
2330 	}
2331       if ((ErrCnt[Failure] + ErrCnt[Serious] == 0) && (ErrCnt[Defect] > 0))
2332 	{
2333 	  printf ("The arithmetic diagnosed may be Acceptable\n");
2334 	  printf ("despite inconvenient Defects.\n");
2335 	}
2336       if ((ErrCnt[Failure] + ErrCnt[Serious]) > 0)
2337 	{
2338 	  printf ("The arithmetic diagnosed has ");
2339 	  printf ("unacceptable Serious Defects.\n");
2340 	}
2341       if (ErrCnt[Failure] > 0)
2342 	{
2343 	  printf ("Potentially fatal FAILURE may have spoiled this");
2344 	  printf (" program's subsequent diagnoses.\n");
2345 	}
2346     }
2347   else
2348     {
2349       printf ("No failures, defects nor flaws have been discovered.\n");
2350       if (!((RMult == Rounded) && (RDiv == Rounded)
2351 	    && (RAddSub == Rounded) && (RSqrt == Rounded)))
2352 	printf ("The arithmetic diagnosed seems Satisfactory.\n");
2353       else
2354 	{
2355 	  if (StickyBit >= One &&
2356 	      (Radix - Two) * (Radix - Nine - One) == Zero)
2357 	    {
2358 	      printf ("Rounding appears to conform to ");
2359 	      printf ("the proposed IEEE standard P");
2360 	      if ((Radix == Two) &&
2361 		  ((Precision - Four * Three * Two) *
2362 		   (Precision - TwentySeven - TwentySeven + One) == Zero))
2363 		printf ("754");
2364 	      else
2365 		printf ("854");
2366 	      if (IEEE)
2367 		printf (".\n");
2368 	      else
2369 		{
2370 		  printf (",\nexcept for possibly Double Rounding");
2371 		  printf (" during Gradual Underflow.\n");
2372 		}
2373 	    }
2374 	  printf ("The arithmetic diagnosed appears to be Excellent!\n");
2375 	}
2376     }
2377   printf ("END OF TEST.\n");
2378   return 0;
2379 }
2380 
2381 template<typename FLOAT>
2382 FLOAT
Sign(FLOAT X)2383 Paranoia<FLOAT>::Sign (FLOAT X)
2384 {
2385   return X >= FLOAT (long (0)) ? 1 : -1;
2386 }
2387 
2388 template<typename FLOAT>
2389 void
Pause()2390 Paranoia<FLOAT>::Pause ()
2391 {
2392   if (do_pause)
2393     {
2394       fputs ("Press return...", stdout);
2395       fflush (stdout);
2396       getchar();
2397     }
2398   printf ("\nDiagnosis resumes after milestone Number %d", Milestone);
2399   printf ("          Page: %d\n\n", PageNo);
2400   ++Milestone;
2401   ++PageNo;
2402 }
2403 
2404 template<typename FLOAT>
2405 void
TstCond(int K,int Valid,const char * T)2406 Paranoia<FLOAT>::TstCond (int K, int Valid, const char *T)
2407 {
2408   if (!Valid)
2409     {
2410       BadCond (K, T);
2411       printf (".\n");
2412     }
2413 }
2414 
2415 template<typename FLOAT>
2416 void
BadCond(int K,const char * T)2417 Paranoia<FLOAT>::BadCond (int K, const char *T)
2418 {
2419   static const char *msg[] = { "FAILURE", "SERIOUS DEFECT", "DEFECT", "FLAW" };
2420 
2421   ErrCnt[K] = ErrCnt[K] + 1;
2422   printf ("%s:  %s", msg[K], T);
2423 }
2424 
2425 /* Random computes
2426      X = (Random1 + Random9)^5
2427      Random1 = X - FLOOR(X) + 0.000005 * X;
2428    and returns the new value of Random1.  */
2429 
2430 template<typename FLOAT>
2431 FLOAT
Random()2432 Paranoia<FLOAT>::Random ()
2433 {
2434   FLOAT X, Y;
2435 
2436   X = Random1 + Random9;
2437   Y = X * X;
2438   Y = Y * Y;
2439   X = X * Y;
2440   Y = X - FLOOR (X);
2441   Random1 = Y + X * FLOAT ("0.000005");
2442   return (Random1);
2443 }
2444 
2445 template<typename FLOAT>
2446 void
SqXMinX(int ErrKind)2447 Paranoia<FLOAT>::SqXMinX (int ErrKind)
2448 {
2449   FLOAT XA, XB;
2450 
2451   XB = X * BInvrse;
2452   XA = X - XB;
2453   SqEr = ((SQRT (X * X) - XB) - XA) / OneUlp;
2454   if (SqEr != Zero)
2455     {
2456       if (SqEr < MinSqEr)
2457 	MinSqEr = SqEr;
2458       if (SqEr > MaxSqEr)
2459 	MaxSqEr = SqEr;
2460       J = J + 1;
2461       BadCond (ErrKind, "\n");
2462       printf ("sqrt(%s) - %s  = %s\n", (X * X).str(), X.str(),
2463 	      (OneUlp * SqEr).str());
2464       printf ("\tinstead of correct value 0 .\n");
2465     }
2466 }
2467 
2468 template<typename FLOAT>
2469 void
NewD()2470 Paranoia<FLOAT>::NewD ()
2471 {
2472   X = Z1 * Q;
2473   X = FLOOR (Half - X / Radix) * Radix + X;
2474   Q = (Q - X * Z) / Radix + X * X * (D / Radix);
2475   Z = Z - Two * X * D;
2476   if (Z <= Zero)
2477     {
2478       Z = -Z;
2479       Z1 = -Z1;
2480     }
2481   D = Radix * D;
2482 }
2483 
2484 template<typename FLOAT>
2485 void
SR3750()2486 Paranoia<FLOAT>::SR3750 ()
2487 {
2488   if (!((X - Radix < Z2 - Radix) || (X - Z2 > W - Z2)))
2489     {
2490       I = I + 1;
2491       X2 = SQRT (X * D);
2492       Y2 = (X2 - Z2) - (Y - Z2);
2493       X2 = X8 / (Y - Half);
2494       X2 = X2 - Half * X2 * X2;
2495       SqEr = (Y2 + Half) + (Half - X2);
2496       if (SqEr < MinSqEr)
2497 	MinSqEr = SqEr;
2498       SqEr = Y2 - X2;
2499       if (SqEr > MaxSqEr)
2500 	MaxSqEr = SqEr;
2501     }
2502 }
2503 
2504 template<typename FLOAT>
2505 void
IsYeqX()2506 Paranoia<FLOAT>::IsYeqX ()
2507 {
2508   if (Y != X)
2509     {
2510       if (N <= 0)
2511 	{
2512 	  if (Z == Zero && Q <= Zero)
2513 	    printf ("WARNING:  computing\n");
2514 	  else
2515 	    BadCond (Defect, "computing\n");
2516 	  printf ("\t(%s) ^ (%s)\n", Z.str(), Q.str());
2517 	  printf ("\tyielded %s;\n", Y.str());
2518 	  printf ("\twhich compared unequal to correct %s ;\n", X.str());
2519 	  printf ("\t\tthey differ by %s .\n", (Y - X).str());
2520 	}
2521       N = N + 1;		/* ... count discrepancies. */
2522     }
2523 }
2524 
2525 template<typename FLOAT>
2526 void
PrintIfNPositive()2527 Paranoia<FLOAT>::PrintIfNPositive ()
2528 {
2529   if (N > 0)
2530     printf ("Similar discrepancies have occurred %d times.\n", N);
2531 }
2532 
2533 template<typename FLOAT>
2534 void
TstPtUf()2535 Paranoia<FLOAT>::TstPtUf ()
2536 {
2537   N = 0;
2538   if (Z != Zero)
2539     {
2540       printf ("Since comparison denies Z = 0, evaluating ");
2541       printf ("(Z + Z) / Z should be safe.\n");
2542       if (setjmp (ovfl_buf))
2543 	goto very_serious;
2544       Q9 = (Z + Z) / Z;
2545       printf ("What the machine gets for (Z + Z) / Z is %s .\n", Q9.str());
2546       if (FABS (Q9 - Two) < Radix * U2)
2547 	{
2548 	  printf ("This is O.K., provided Over/Underflow");
2549 	  printf (" has NOT just been signaled.\n");
2550 	}
2551       else
2552 	{
2553 	  if ((Q9 < One) || (Q9 > Two))
2554 	    {
2555 	    very_serious:
2556 	      N = 1;
2557 	      ErrCnt[Serious] = ErrCnt[Serious] + 1;
2558 	      printf ("This is a VERY SERIOUS DEFECT!\n");
2559 	    }
2560 	  else
2561 	    {
2562 	      N = 1;
2563 	      ErrCnt[Defect] = ErrCnt[Defect] + 1;
2564 	      printf ("This is a DEFECT!\n");
2565 	    }
2566 	}
2567       V9 = Z * One;
2568       Random1 = V9;
2569       V9 = One * Z;
2570       Random2 = V9;
2571       V9 = Z / One;
2572       if ((Z == Random1) && (Z == Random2) && (Z == V9))
2573 	{
2574 	  if (N > 0)
2575 	    Pause ();
2576 	}
2577       else
2578 	{
2579 	  N = 1;
2580 	  BadCond (Defect, "What prints as Z = ");
2581 	  printf ("%s\n\tcompares different from  ", Z.str());
2582 	  if (Z != Random1)
2583 	    printf ("Z * 1 = %s ", Random1.str());
2584 	  if (!((Z == Random2) || (Random2 == Random1)))
2585 	    printf ("1 * Z == %s\n", Random2.str());
2586 	  if (!(Z == V9))
2587 	    printf ("Z / 1 = %s\n", V9.str());
2588 	  if (Random2 != Random1)
2589 	    {
2590 	      ErrCnt[Defect] = ErrCnt[Defect] + 1;
2591 	      BadCond (Defect, "Multiplication does not commute!\n");
2592 	      printf ("\tComparison alleges that 1 * Z = %s\n", Random2.str());
2593 	      printf ("\tdiffers from Z * 1 = %s\n", Random1.str());
2594 	    }
2595 	  Pause ();
2596 	}
2597     }
2598 }
2599 
2600 template<typename FLOAT>
2601 void
notify(const char * s)2602 Paranoia<FLOAT>::notify (const char *s)
2603 {
2604   printf ("%s test appears to be inconsistent...\n", s);
2605   printf ("   PLEASE NOTIFY KARPINKSI!\n");
2606 }
2607 
2608 /* ====================================================================== */
2609 
main(int ac,char ** av)2610 int main(int ac, char **av)
2611 {
2612   setbuf(stdout, NULL);
2613   setbuf(stderr, NULL);
2614 
2615   while (1)
2616     switch (getopt (ac, av, "pvg:fdl"))
2617       {
2618       case -1:
2619 	return 0;
2620       case 'p':
2621 	do_pause = true;
2622 	break;
2623       case 'v':
2624 	verbose = true;
2625 	break;
2626       case 'g':
2627 	{
2628 	  static const struct {
2629 	    const char *name;
2630 	    const struct real_format *fmt;
2631 	  } fmts[] = {
2632 #define F(x) { #x, &x##_format }
2633 	    F(ieee_single),
2634 	    F(ieee_double),
2635 	    F(ieee_extended_motorola),
2636 	    F(ieee_extended_intel_96),
2637 	    F(ieee_extended_intel_128),
2638 	    F(ibm_extended),
2639 	    F(ieee_quad),
2640 	    F(vax_f),
2641 	    F(vax_d),
2642 	    F(vax_g),
2643 	    F(i370_single),
2644 	    F(i370_double),
2645 	    F(real_internal),
2646 #undef F
2647 	  };
2648 
2649 	  int i, n = sizeof (fmts)/sizeof(*fmts);
2650 
2651 	  for (i = 0; i < n; ++i)
2652 	    if (strcmp (fmts[i].name, optarg) == 0)
2653 	      break;
2654 
2655 	  if (i == n)
2656 	    {
2657 	      printf ("Unknown implementation \"%s\"; "
2658 		      "available implementations:\n", optarg);
2659 	      for (i = 0; i < n; ++i)
2660 		printf ("\t%s\n", fmts[i].name);
2661 	      return 1;
2662 	    }
2663 
2664 	  // We cheat and use the same mode all the time, but vary
2665 	  // the format used for that mode.
2666 	  real_format_for_mode[int(real_c_float::MODE) - int(QFmode)]
2667 	    = fmts[i].fmt;
2668 
2669 	  Paranoia<real_c_float>().main();
2670 	  break;
2671 	}
2672 
2673       case 'f':
2674 	Paranoia < native_float<float> >().main();
2675 	break;
2676       case 'd':
2677 	Paranoia < native_float<double> >().main();
2678 	break;
2679       case 'l':
2680 #ifndef NO_LONG_DOUBLE
2681 	Paranoia < native_float<long double> >().main();
2682 #endif
2683 	break;
2684 
2685       case '?':
2686 	puts ("-p\tpause between pages");
2687 	puts ("-g<FMT>\treal.c implementation FMT");
2688 	puts ("-f\tnative float");
2689 	puts ("-d\tnative double");
2690 	puts ("-l\tnative long double");
2691 	return 0;
2692       }
2693 }
2694 
2695 /* GCC stuff referenced by real.o.  */
2696 
2697 extern "C" void
fancy_abort()2698 fancy_abort ()
2699 {
2700   abort ();
2701 }
2702 
2703 int target_flags = 0;
2704 
2705 extern "C" int
floor_log2_wide(unsigned HOST_WIDE_INT x)2706 floor_log2_wide (unsigned HOST_WIDE_INT x)
2707 {
2708   int log = -1;
2709   while (x != 0)
2710     log++,
2711     x >>= 1;
2712   return log;
2713 }
2714