#include <stdio.h>
#include <signal.h>
#include <setjmp.h>
Include dependency graph for paranoia.c:

Go to the source code of this file.
Defines | |
| #define | Chopped 2 |
| #define | Defect 2 |
| #define | FABS(x) fabs(x) |
| #define | Failure 0 |
| #define | False 0 |
| #define | Flaw 3 |
| #define | FLOAT double |
| #define | FLOOR(x) floor(x) |
| #define | KEYBOARD 0 |
| #define | LOG(x) log(x) |
| #define | No 0 |
| #define | NOPAUSE |
| #define | Other 0 |
| #define | POW(x, y) pow(x,y) |
| #define | Rounded 1 |
| #define | Serious 1 |
| #define | SQRT(x) sqrt(x) |
| #define | True 1 |
| #define | Yes 1 |
Typedefs | |
| typedef int | Class |
| typedef int | Guard |
| typedef char | Message |
| typedef int | Rounding |
| typedef void(* | Sig_type )() |
Functions | |
| BadCond (int K, char *T) | |
| Characteristics () | |
| double | fabs () |
| double | floor () |
| Heading () | |
| History () | |
| Instructions () | |
| IsYeqX () | |
| double | log () |
| main () | |
| msglist (char **s) | |
| NewD () | |
| notify (char *s) | |
| Pause () | |
| double | pow (double x, double y) |
| double | pow () |
| PrintIfNPositive () | |
| FLOAT | Random () |
| void | sigfpe (i) |
| FLOAT | Sign (FLOAT X) |
| FLOAT | Sign () |
| double | sqrt () |
| SqXMinX (int ErrKind) | |
| SR3750 () | |
| SR3980 () | |
| TstCond (int K, int Valid, char *T) | |
| TstPtUf () | |
Variables | |
| FLOAT | A1 |
| FLOAT | AInvrse |
| int | Anomaly |
| FLOAT | BInvrse |
| FLOAT | BMinusU2 |
| int | Break |
| FLOAT | C |
| char | ch [8] |
| FLOAT | CInvrse |
| FLOAT | D |
| int | Done |
| FLOAT | E0 |
| FLOAT | E1 |
| FLOAT | E3 |
| FLOAT | E9 |
| FLOAT | Eight = 8.0 |
| int | ErrCnt [4] |
| FLOAT | Exp2 |
| FLOAT | F6 |
| FLOAT | F9 |
| FLOAT | Five = 5.0 |
| FLOAT | Four = 4.0 |
| FLOAT | FourD |
| int | fpecount |
| Guard | GAddSub |
| Guard | GDiv |
| Guard | GMult |
| FLOAT | H |
| FLOAT | Half = 0.5 |
| FLOAT | HInvrse |
| int | I |
| int | IEEE |
| int | Indx |
| FLOAT | J |
| int | M |
| FLOAT | MaxSqEr |
| int | Milestone |
| FLOAT | MinSqEr |
| FLOAT | MinusOne = -1.0 |
| int | Monot |
| FLOAT | MyZero |
| int | N |
| int | N1 |
| FLOAT | Nine = 9.0 |
| int | NotMonot |
| int | NoTrials = 20 |
| FLOAT | One = 1.0 |
| FLOAT | OneAndHalf = 1.5 |
| FLOAT | OneUlp |
| jmp_buf | ovfl_buf |
| int | PageNo |
| FLOAT | Precision |
| FLOAT | PseudoZero |
| FLOAT | Q |
| FLOAT | Q9 |
| FLOAT | R |
| Rounding | RAddSub |
| FLOAT | Radix |
| FLOAT | RadixD2 |
| FLOAT | Random1 |
| FLOAT | Random2 |
| FLOAT | Random9 |
| Rounding | RDiv |
| Rounding | RMult |
| Rounding | RSqrt |
| FLOAT | S |
| Sig_type | sigsave |
| FLOAT | SqEr |
| int | SqRWrng |
| FLOAT | StickyBit |
| FLOAT | T |
| FLOAT | Third |
| FLOAT | ThirtyTwo = 32.0 |
| FLOAT | Three = 3.0 |
| FLOAT | TwentySeven = 27.0 |
| FLOAT | Two = 2.0 |
| FLOAT | TwoForty = 240.0 |
| FLOAT | U1 |
| FLOAT | U2 |
| int | UfNGrad |
| FLOAT | UfThold |
| FLOAT | Underflow |
| FLOAT | V |
| FLOAT | V0 |
| FLOAT | V9 |
| FLOAT | W |
| FLOAT | X |
| FLOAT | X1 |
| FLOAT | X2 |
| FLOAT | X8 |
| FLOAT | Y |
| FLOAT | Y1 |
| FLOAT | Y2 |
| FLOAT | Z |
| FLOAT | Z1 |
| FLOAT | Z2 |
| FLOAT | Z9 |
| FLOAT | Zero = 0.0 |
|
|
Definition at line 278 of file paranoia.c. |
|
|
Definition at line 282 of file paranoia.c. |
|
|
Definition at line 234 of file paranoia.c. |
|
|
Definition at line 284 of file paranoia.c. Referenced by main(). |
|
|
Definition at line 267 of file paranoia.c. Referenced by GLW_SetMode(), install_grabs(), and main(). |
|
|
Definition at line 281 of file paranoia.c. Referenced by main(). |
|
|
Definition at line 233 of file paranoia.c. Referenced by asgncode(), constant(), do_type(), emittype(), eqtype(), hasproto(), outtype(), postfix(), primary(), promote(), prtype(), Random(), Sign(), specifier(), SqXMinX(), tracevalue(), ttob(), type_init(), typestring(), typeuid(), uid2type(), vtoa(), and xxinit(). |
|
|
Definition at line 235 of file paranoia.c. |
|
|
Definition at line 245 of file paranoia.c. |
|
|
Definition at line 236 of file paranoia.c. |
|
|
Definition at line 277 of file paranoia.c. Referenced by main(). |
|
|
Definition at line 2 of file paranoia.c. |
|
|
Definition at line 280 of file paranoia.c. Referenced by main(). |
|
|
Definition at line 237 of file paranoia.c. |
|
|
Definition at line 279 of file paranoia.c. |
|
|
Definition at line 283 of file paranoia.c. Referenced by main(). |
|
|
Definition at line 238 of file paranoia.c. |
|
|
Definition at line 268 of file paranoia.c. Referenced by GLW_SetMode(), and install_grabs(). |
|
|
Definition at line 276 of file paranoia.c. Referenced by main(). |
|
|
Definition at line 285 of file paranoia.c. |
|
|
Definition at line 285 of file paranoia.c. |
|
|
Definition at line 286 of file paranoia.c. |
|
|
Definition at line 285 of file paranoia.c. |
|
|
Definition at line 242 of file paranoia.c. |
|
||||||||||||
|
Definition at line 1876 of file paranoia.c. References ErrCnt, printf(), and T. Referenced by IsYeqX(), main(), SqXMinX(), TstCond(), and TstPtUf(). 01879 {
01880 static char *msg[] = { "FAILURE", "SERIOUS DEFECT", "DEFECT", "FLAW" };
01881
01882 ErrCnt [K] = ErrCnt [K] + 1;
01883 printf("%s: %s", msg[K], T);
01884 }
|
Here is the call graph for this function:

|
|
Definition at line 2119 of file paranoia.c. References msglist(). Referenced by main(). 02120 {
02121 static char *chars[] = {
02122 "Running this program should reveal these characteristics:",
02123 " Radix = 1, 2, 4, 8, 10, 16, 100, 256 ...",
02124 " Precision = number of significant digits carried.",
02125 " U2 = Radix/Radix^Precision = One Ulp",
02126 "\t(OneUlpnit in the Last Place) of 1.000xxx .",
02127 " U1 = 1/Radix^Precision = One Ulp of numbers a little less than 1.0 .",
02128 " Adequacy of guard digits for Mult., Div. and Subt.",
02129 " Whether arithmetic is chopped, correctly rounded, or something else",
02130 "\tfor Mult., Div., Add/Subt. and Sqrt.",
02131 " Whether a Sticky Bit used correctly for rounding.",
02132 " UnderflowThreshold = an underflow threshold.",
02133 " E0 and PseudoZero tell whether underflow is abrupt, gradual, or fuzzy.",
02134 " V = an overflow threshold, roughly.",
02135 " V0 tells, roughly, whether Infinity is represented.",
02136 " Comparisions are checked for consistency with subtraction",
02137 "\tand for contamination with pseudo-zeros.",
02138 " Sqrt is tested. Y^X is not tested.",
02139 " Extra-precise subexpressions are revealed but NOT YET tested.",
02140 " Decimal-Binary conversion is NOT YET tested for accuracy.",
02141 0};
02142
02143 msglist(chars);
02144 }
|
Here is the call graph for this function:

|
|
|
|
Definition at line 2091 of file paranoia.c. References head, and msglist(). Referenced by main(). 02092 {
02093 static char *head[] = {
02094 "Users are invited to help debug and augment this program so it will",
02095 "cope with unanticipated and newly uncovered arithmetic pathologies.\n",
02096 "Please send suggestions and interesting results to",
02097 "\tRichard Karpinski",
02098 "\tComputer Center U-76",
02099 "\tUniversity of California",
02100 "\tSan Francisco, CA 94143-0704, USA\n",
02101 "In doing so, please include the following information:",
02102 #ifdef Single
02103 "\tPrecision:\tsingle;",
02104 #else
02105 "\tPrecision:\tdouble;",
02106 #endif
02107 "\tVersion:\t10 February 1989;",
02108 "\tComputer:\n",
02109 "\tCompiler:\n",
02110 "\tOptimization level:\n",
02111 "\tOther relevant compiler options:",
02112 0};
02113
02114 msglist(head);
02115 }
|
Here is the call graph for this function:

|
|
Definition at line 2146 of file paranoia.c. References msglist(). Referenced by main(). 02148 { /* History */
02149 /* Converted from Brian Wichmann's Pascal version to C by Thos Sumner,
02150 with further massaging by David M. Gay. */
02151
02152 static char *hist[] = {
02153 "The program attempts to discriminate among",
02154 " FLAWs, like lack of a sticky bit,",
02155 " Serious DEFECTs, like lack of a guard digit, and",
02156 " FAILUREs, like 2+2 == 5 .",
02157 "Failures may confound subsequent diagnoses.\n",
02158 "The diagnostic capabilities of this program go beyond an earlier",
02159 "program called `MACHAR', which can be found at the end of the",
02160 "book `Software Manual for the Elementary Functions' (1980) by",
02161 "W. J. Cody and W. Waite. Although both programs try to discover",
02162 "the Radix, Precision and range (over/underflow thresholds)",
02163 "of the arithmetic, this program tries to cope with a wider variety",
02164 "of pathologies, and to say how well the arithmetic is implemented.",
02165 "\nThe program is based upon a conventional radix representation for",
02166 "floating-point numbers, but also allows logarithmic encoding",
02167 "as used by certain early WANG machines.\n",
02168 "BASIC version of this program (C) 1983 by Prof. W. M. Kahan;",
02169 "see source comments for more history.",
02170 0};
02171
02172 msglist(hist);
02173 }
|
Here is the call graph for this function:

|
|
Definition at line 2072 of file paranoia.c. References msglist(). Referenced by main(). 02073 {
02074 static char *instr[] = {
02075 "Lest this program stop prematurely, i.e. before displaying\n",
02076 " `END OF TEST',\n",
02077 "try to persuade the computer NOT to terminate execution when an",
02078 "error like Over/Underflow or Division by Zero occurs, but rather",
02079 "to persevere with a surrogate value after, perhaps, displaying some",
02080 "warning. If persuasion avails naught, don't despair but run this",
02081 "program anyway to see how many milestones it passes, and then",
02082 "amend it to make further progress.\n",
02083 "Answer questions with Y, y, N or n (unless otherwise indicated).\n",
02084 0};
02085
02086 msglist(instr);
02087 }
|
Here is the call graph for this function:

|
|
Definition at line 1960 of file paranoia.c. References BadCond(), Defect, N, printf(), Q, X, Y, Z, and Zero. Referenced by main(), and SR3980(). 01961 {
01962 if (Y != X) {
01963 if (N <= 0) {
01964 if (Z == Zero && Q <= Zero)
01965 printf("WARNING: computing\n");
01966 else BadCond(Defect, "computing\n");
01967 printf("\t(%.17e) ^ (%.17e)\n", Z, Q);
01968 printf("\tyielded %.17e;\n", Y);
01969 printf("\twhich compared unequal to correct %.17e ;\n",
01970 X);
01971 printf("\t\tthey differ by %.17e .\n", Y - X);
01972 }
01973 N = N + 1; /* ... count discrepancies. */
01974 }
01975 }
|
Here is the call graph for this function:

|
|
Referenced by pow(). |
|
|
Definition at line 342 of file paranoia.c. References A1, AInvrse, Anomaly, BadCond(), BInvrse, BMinusU2, Break, C, ch, Characteristics(), CInvrse, D, Defect, Done, E0, E1, E3, E9, Eight, ErrCnt, Exp2, F6, F9, FABS, Failure, False, fflush(), Five, Flaw, FLOOR, Four, FourD, fpecount, GAddSub, GDiv, GMult, H, Half, Heading(), HInvrse, History(), i, I, IEEE, Indx, Instructions(), IsYeqX(), J, KEYBOARD, LOG, M, MaxSqEr, Milestone, MinSqEr, MinusOne, Monot, MyZero, N, N1, NewD(), Nine, No, notify(), NotMonot, NoTrials, One, OneAndHalf, OneUlp, Other, ovfl_buf, PageNo, Pause(), POW, Precision, printf(), PrintIfNPositive(), PseudoZero, Q, R, RAddSub, Radix, RadixD2, Random(), Random1, Random2, Random9, RDiv, read(), RMult, RSqrt, S, Serious, setjmp(), sigfpe(), SIGFPE, Sign, signal, sigsave, SqEr, SQRT, SqRWrng, SqXMinX(), SR3750(), SR3980(), stdout, StickyBit, T, Third, ThirtyTwo, Three, TstCond(), TstPtUf(), TwentySeven, Two, TwoForty, U1, U2, UfNGrad, UfThold, Underflow, V, V0, V9, W, X, X1, X8, Y, Y1, Y2, Yes, Z, Z1, Z2, Z9, and Zero. 00343 {
00344 #ifdef mc
00345 char *out;
00346 ieee_flags("set", "precision", "double", &out);
00347 #endif
00348 /* First two assignments use integer right-hand sides. */
00349 Zero = 0;
00350 One = 1;
00351 Two = One + One;
00352 Three = Two + One;
00353 Four = Three + One;
00354 Five = Four + One;
00355 Eight = Four + Four;
00356 Nine = Three * Three;
00357 TwentySeven = Nine * Three;
00358 ThirtyTwo = Four * Eight;
00359 TwoForty = Four * Five * Three * Four;
00360 MinusOne = -One;
00361 Half = One / Two;
00362 OneAndHalf = One + Half;
00363 ErrCnt[Failure] = 0;
00364 ErrCnt[Serious] = 0;
00365 ErrCnt[Defect] = 0;
00366 ErrCnt[Flaw] = 0;
00367 PageNo = 1;
00368 /*=============================================*/
00369 Milestone = 0;
00370 /*=============================================*/
00371 #ifndef NOSIGNAL
00372 signal(SIGFPE, sigfpe);
00373 #endif
00374 Instructions();
00375 Pause();
00376 Heading();
00377 Pause();
00378 Characteristics();
00379 Pause();
00380 History();
00381 Pause();
00382 /*=============================================*/
00383 Milestone = 7;
00384 /*=============================================*/
00385 printf("Program is now RUNNING tests on small integers:\n");
00386
00387 TstCond (Failure, (Zero + Zero == Zero) && (One - One == Zero)
00388 && (One > Zero) && (One + One == Two),
00389 "0+0 != 0, 1-1 != 0, 1 <= 0, or 1+1 != 2");
00390 Z = - Zero;
00391 if (Z != 0.0) {
00392 ErrCnt[Failure] = ErrCnt[Failure] + 1;
00393 printf("Comparison alleges that -0.0 is Non-zero!\n");
00394 U1 = 0.001;
00395 Radix = 1;
00396 TstPtUf();
00397 }
00398 TstCond (Failure, (Three == Two + One) && (Four == Three + One)
00399 && (Four + Two * (- Two) == Zero)
00400 && (Four - Three - One == Zero),
00401 "3 != 2+1, 4 != 3+1, 4+2*(-2) != 0, or 4-3-1 != 0");
00402 TstCond (Failure, (MinusOne == (0 - One))
00403 && (MinusOne + One == Zero ) && (One + MinusOne == Zero)
00404 && (MinusOne + FABS(One) == Zero)
00405 && (MinusOne + MinusOne * MinusOne == Zero),
00406 "-1+1 != 0, (-1)+abs(1) != 0, or -1+(-1)*(-1) != 0");
00407 TstCond (Failure, Half + MinusOne + Half == Zero,
00408 "1/2 + (-1) + 1/2 != 0");
00409 /*=============================================*/
00410 /*SPLIT
00411 part2();
00412 part3();
00413 part4();
00414 part5();
00415 part6();
00416 part7();
00417 part8();
00418 }
00419 #include "paranoia.h"
00420 part2(){
00421 */
00422 Milestone = 10;
00423 /*=============================================*/
00424 TstCond (Failure, (Nine == Three * Three)
00425 && (TwentySeven == Nine * Three) && (Eight == Four + Four)
00426 && (ThirtyTwo == Eight * Four)
00427 && (ThirtyTwo - TwentySeven - Four - One == Zero),
00428 "9 != 3*3, 27 != 9*3, 32 != 8*4, or 32-27-4-1 != 0");
00429 TstCond (Failure, (Five == Four + One) &&
00430 (TwoForty == Four * Five * Three * Four)
00431 && (TwoForty / Three - Four * Four * Five == Zero)
00432 && ( TwoForty / Four - Five * Three * Four == Zero)
00433 && ( TwoForty / Five - Four * Three * Four == Zero),
00434 "5 != 4+1, 240/3 != 80, 240/4 != 60, or 240/5 != 48");
00435 if (ErrCnt[Failure] == 0) {
00436 printf("-1, 0, 1/2, 1, 2, 3, 4, 5, 9, 27, 32 & 240 are O.K.\n");
00437 printf("\n");
00438 }
00439 printf("Searching for Radix and Precision.\n");
00440 W = One;
00441 do {
00442 W = W + W;
00443 Y = W + One;
00444 Z = Y - W;
00445 Y = Z - One;
00446 } while (MinusOne + FABS(Y) < Zero);
00447 /*.. now W is just big enough that |((W+1)-W)-1| >= 1 ...*/
00448 Precision = Zero;
00449 Y = One;
00450 do {
00451 Radix = W + Y;
00452 Y = Y + Y;
00453 Radix = Radix - W;
00454 } while ( Radix == Zero);
00455 if (Radix < Two) Radix = One;
00456 printf("Radix = %f .\n", Radix);
00457 if (Radix != 1) {
00458 W = One;
00459 do {
00460 Precision = Precision + One;
00461 W = W * Radix;
00462 Y = W + One;
00463 } while ((Y - W) == One);
00464 }
00465 /*... now W == Radix^Precision is barely too big to satisfy (W+1)-W == 1
00466 ...*/
00467 U1 = One / W;
00468 U2 = Radix * U1;
00469 printf("Closest relative separation found is U1 = %.7e .\n\n", U1);
00470 printf("Recalculating radix and precision\n ");
00471
00472 /*save old values*/
00473 E0 = Radix;
00474 E1 = U1;
00475 E9 = U2;
00476 E3 = Precision;
00477
00478 X = Four / Three;
00479 Third = X - One;
00480 F6 = Half - Third;
00481 X = F6 + F6;
00482 X = FABS(X - Third);
00483 if (X < U2) X = U2;
00484
00485 /*... now X = (unknown no.) ulps of 1+...*/
00486 do {
00487 U2 = X;
00488 Y = Half * U2 + ThirtyTwo * U2 * U2;
00489 Y = One + Y;
00490 X = Y - One;
00491 } while ( ! ((U2 <= X) || (X <= Zero)));
00492
00493 /*... now U2 == 1 ulp of 1 + ... */
00494 X = Two / Three;
00495 F6 = X - Half;
00496 Third = F6 + F6;
00497 X = Third - Half;
00498 X = FABS(X + F6);
00499 if (X < U1) X = U1;
00500
00501 /*... now X == (unknown no.) ulps of 1 -... */
00502 do {
00503 U1 = X;
00504 Y = Half * U1 + ThirtyTwo * U1 * U1;
00505 Y = Half - Y;
00506 X = Half + Y;
00507 Y = Half - X;
00508 X = Half + Y;
00509 } while ( ! ((U1 <= X) || (X <= Zero)));
00510 /*... now U1 == 1 ulp of 1 - ... */
00511 if (U1 == E1) printf("confirms closest relative separation U1 .\n");
00512 else printf("gets better closest relative separation U1 = %.7e .\n", U1);
00513 W = One / U1;
00514 F9 = (Half - U1) + Half;
00515 Radix = FLOOR(0.01 + U2 / U1);
00516 if (Radix == E0) printf("Radix confirmed.\n");
00517 else printf("MYSTERY: recalculated Radix = %.7e .\n", Radix);
00518 TstCond (Defect, Radix <= Eight + Eight,
00519 "Radix is too big: roundoff problems");
00520 TstCond (Flaw, (Radix == Two) || (Radix == 10)
00521 || (Radix == One), "Radix is not as good as 2 or 10");
00522 /*=============================================*/
00523 Milestone = 20;
00524 /*=============================================*/
00525 TstCond (Failure, F9 - Half < Half,
00526 "(1-U1)-1/2 < 1/2 is FALSE, prog. fails?");
00527 X = F9;
00528 I = 1;
00529 Y = X - Half;
00530 Z = Y - Half;
00531 TstCond (Failure, (X != One)
00532 || (Z == Zero), "Comparison is fuzzy,X=1 but X-1/2-1/2 != 0");
00533 X = One + U2;
00534 I = 0;
00535 /*=============================================*/
00536 Milestone = 25;
00537 /*=============================================*/
00538 /*... BMinusU2 = nextafter(Radix, 0) */
00539 BMinusU2 = Radix - One;
00540 BMinusU2 = (BMinusU2 - U2) + One;
00541 /* Purify Integers */
00542 if (Radix != One) {
00543 X = - TwoForty * LOG(U1) / LOG(Radix);
00544 Y = FLOOR(Half + X);
00545 if (FABS(X - Y) * Four < One) X = Y;
00546 Precision = X / TwoForty;
00547 Y = FLOOR(Half + Precision);
00548 if (FABS(Precision - Y) * TwoForty < Half) Precision = Y;
00549 }
00550 if ((Precision != FLOOR(Precision)) || (Radix == One)) {
00551 printf("Precision cannot be characterized by an Integer number\n");
00552 printf("of significant digits but, by itself, this is a minor flaw.\n");
00553 }
00554 if (Radix == One)
00555 printf("logarithmic encoding has precision characterized solely by U1.\n");
00556 else printf("The number of significant digits of the Radix is %f .\n",
00557 Precision);
00558 TstCond (Serious, U2 * Nine * Nine * TwoForty < One,
00559 "Precision worse than 5 decimal figures ");
00560 /*=============================================*/
00561 Milestone = 30;
00562 /*=============================================*/
00563 /* Test for extra-precise subepressions */
00564 X = FABS(((Four / Three - One) - One / Four) * Three - One / Four);
00565 do {
00566 Z2 = X;
00567 X = (One + (Half * Z2 + ThirtyTwo * Z2 * Z2)) - One;
00568 } while ( ! ((Z2 <= X) || (X <= Zero)));
00569 X = Y = Z = FABS((Three / Four - Two / Three) * Three - One / Four);
00570 do {
00571 Z1 = Z;
00572 Z = (One / Two - ((One / Two - (Half * Z1 + ThirtyTwo * Z1 * Z1))
00573 + One / Two)) + One / Two;
00574 } while ( ! ((Z1 <= Z) || (Z <= Zero)));
00575 do {
00576 do {
00577 Y1 = Y;
00578 Y = (Half - ((Half - (Half * Y1 + ThirtyTwo * Y1 * Y1)) + Half
00579 )) + Half;
00580 } while ( ! ((Y1 <= Y) || (Y <= Zero)));
00581 X1 = X;
00582 X = ((Half * X1 + ThirtyTwo * X1 * X1) - F9) + F9;
00583 } while ( ! ((X1 <= X) || (X <= Zero)));
00584 if ((X1 != Y1) || (X1 != Z1)) {
00585 BadCond(Serious, "Disagreements among the values X1, Y1, Z1,\n");
00586 printf("respectively %.7e, %.7e, %.7e,\n", X1, Y1, Z1);
00587 printf("are symptoms of inconsistencies introduced\n");
00588 printf("by extra-precise evaluation of arithmetic subexpressions.\n");
00589 notify("Possibly some part of this");
00590 if ((X1 == U1) || (Y1 == U1) || (Z1 == U1)) printf(
00591 "That feature is not tested further by this program.\n") ;
00592 }
00593 else {
00594 if ((Z1 != U1) || (Z2 != U2)) {
00595 if ((Z1 >= U1) || (Z2 >= U2)) {
00596 BadCond(Failure, "");
00597 notify("Precision");
00598 printf("\tU1 = %.7e, Z1 - U1 = %.7e\n",U1,Z1-U1);
00599 printf("\tU2 = %.7e, Z2 - U2 = %.7e\n",U2,Z2-U2);
00600 }
00601 else {
00602 if ((Z1 <= Zero) || (Z2 <= Zero)) {
00603 printf("Because of unusual Radix = %f", Radix);
00604 printf(", or exact rational arithmetic a result\n");
00605 printf("Z1 = %.7e, or Z2 = %.7e ", Z1, Z2);
00606 notify("of an\nextra-precision");
00607 }
00608 if (Z1 != Z2 || Z1 > Zero) {
00609 X = Z1 / U1;
00610 Y = Z2 / U2;
00611 if (Y > X) X = Y;
00612 Q = - LOG(X);
00613 printf("Some subexpressions appear to be calculated extra\n");
00614 printf("precisely with about %g extra B-digits, i.e.\n",
00615 (Q / LOG(Radix)));
00616 printf("roughly %g extra significant decimals.\n",
00617 Q / LOG(10.));
00618 }
00619 printf("That feature is not tested further by this program.\n");
00620 }
00621 }
00622 }
00623 Pause();
00624 /*=============================================*/
00625 /*SPLIT
00626 }
00627 #include "paranoia.h"
00628 part3(){
00629 */
00630 Milestone = 35;
00631 /*=============================================*/
00632 if (Radix >= Two) {
00633 X = W / (Radix * Radix);
00634 Y = X + One;
00635 Z = Y - X;
00636 T = Z + U2;
00637 X = T - Z;
00638 TstCond (Failure, X == U2,
00639 "Subtraction is not normalized X=Y,X+Z != Y+Z!");
00640 if (X == U2) printf(
00641 "Subtraction appears to be normalized, as it should be.");
00642 }
00643 printf("\nChecking for guard digit in *, /, and -.\n");
00644 Y = F9 * One;
00645 Z = One * F9;
00646 X = F9 - Half;
00647 Y = (Y - Half) - X;
00648 Z = (Z - Half) - X;
00649 X = One + U2;
00650 T = X * Radix;
00651 R = Radix * X;
00652 X = T - Radix;
00653 X = X - |