Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

paranoia.c File Reference

#include <stdio.h>
#include <signal.h>
#include <setjmp.h>

Include dependency graph for paranoia.c:

Include dependency graph

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


Define Documentation

#define Chopped   2
 

Definition at line 278 of file paranoia.c.

#define Defect   2
 

Definition at line 282 of file paranoia.c.

Referenced by IsYeqX(), main(), and TstPtUf().

#define FABS  )     fabs(x)
 

Definition at line 234 of file paranoia.c.

Referenced by main(), and TstPtUf().

#define Failure   0
 

Definition at line 284 of file paranoia.c.

Referenced by main().

#define False   0
 

Definition at line 267 of file paranoia.c.

Referenced by GLW_SetMode(), install_grabs(), and main().

#define Flaw   3
 

Definition at line 281 of file paranoia.c.

Referenced by main().

#define FLOAT   double
 

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().

#define FLOOR  )     floor(x)
 

Definition at line 235 of file paranoia.c.

Referenced by main(), NewD(), and Random().

#define KEYBOARD   0
 

Definition at line 245 of file paranoia.c.

Referenced by main(), and Pause().

#define LOG  )     log(x)
 

Definition at line 236 of file paranoia.c.

#define No   0
 

Definition at line 277 of file paranoia.c.

Referenced by main().

#define NOPAUSE
 

Definition at line 2 of file paranoia.c.

#define Other   0
 

Definition at line 280 of file paranoia.c.

Referenced by main().

#define POW x,
y   )     pow(x,y)
 

Definition at line 237 of file paranoia.c.

Referenced by main(), and SR3980().

#define Rounded   1
 

Definition at line 279 of file paranoia.c.

#define Serious   1
 

Definition at line 283 of file paranoia.c.

Referenced by main().

#define SQRT  )     sqrt(x)
 

Definition at line 238 of file paranoia.c.

Referenced by main(), SqXMinX(), and SR3750().

#define True   1
 

Definition at line 268 of file paranoia.c.

Referenced by GLW_SetMode(), and install_grabs().

#define Yes   1
 

Definition at line 276 of file paranoia.c.

Referenced by main().


Typedef Documentation

typedef int Class
 

Definition at line 285 of file paranoia.c.

typedef int Guard
 

Definition at line 285 of file paranoia.c.

typedef char Message
 

Definition at line 286 of file paranoia.c.

typedef int Rounding
 

Definition at line 285 of file paranoia.c.

typedef void(* Sig_type)()
 

Definition at line 242 of file paranoia.c.


Function Documentation

BadCond int  K,
char *  T
 

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:

Characteristics  ) 
 

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:

double fabs  ) 
 

Referenced by AAS_AddPlaneToHash(), AAS_CheckArea(), AAS_CheckFaceWindingPlane(), AAS_FallDelta(), AAS_FindHashedPlane(), AAS_FlipAreaFaces(), AAS_GetVertex(), AAS_PlaneTypeForNormal(), AAS_Reachability_Jump(), AAS_Reachability_JumpPad(), AAS_Reachability_Step_Barrier_WaterJump_WalkOffLedge(), AAS_Reachability_WalkOffLedge(), AddEdge(), AddPlaneToHash(), AddPoint(), AddSkyPolygon(), AllocateLightmapForSurface(), AxializeVector(), Back(), BaseWindingForPlane(), BG_TouchJumpPad(), BotAimAtEnemy(), BotCheckBlocked(), BotFindCachedCharacter(), BotFinishTravel_Elevator(), BotFuncButtonActivateGoal(), BotTravel_BFGJump(), BotTravel_Grapple(), BotTravel_RocketJump(), Brush_MakeFaceWinding(), Brush_SelectFaceForDragging(), CEpairsWrapper::CalculateRotatedBounds(), CCamWnd::Cam_MouseControl(), CG_CalcViewValues(), CG_PlayerFlag(), CG_SwingAngles(), CM_DistanceFromLineSquared(), CM_DrawDebugSurface(), CM_GenerateFacetFor4Points(), CM_PlaneEqual(), CM_PositionTestInPatchCollide(), CM_SnapVector(), CM_Trace(), CM_TraceThroughPatchCollide(), CM_TraceThroughTree(), ComputeAxisBase(), ComputeBest2DVector(), Controls_SetConfig(), CreateFilters(), DistanceFromLineSquared(), EmitBrushPrimitTextureCoordinates(), FindFloatPlane(), FindPoint(), GetVertexnum(), LoadModel(), PatchMapDrawSurfs(), PerpendicularVector(), Plane_Equal(), PlaneEqual(), PlaneTypeForNormal(), Point_Equal(), ProjectOnPlane(), ProjectRadius(), Q2_BrushSideWinding(), Q3_BrushSideWinding(), Q3_FindVisibleBrushSides(), R_FixSharedVertexLodError_r(), R_MergedHeightPoints(), R_MergedWidthPoints(), R_StitchPatches(), Bounds::Radius(), RadiusFromBounds(), SetShadeForPlane(), Sin_BrushSideWinding(), SnapPlane(), SnapVector(), SP_func_button(), SP_func_door(), SP_func_pendulum(), Terrain_AddMovePoint(), TestEdge(), TestExpandBrushes(), TexMatToFakeTexCoords(), TextureMatrixFromPoints(), TH_AddPlaneToHash(), TH_FindFloatPlane(), TH_FindTetrahedron2(), TH_FindVertex(), TH_PlaneEqual(), TH_PlaneTypeForNormal(), TH_SnapPlane(), TH_SnapVector(), Touch_DoorTriggerSpectator(), TryMergeWinding(), UI_SwingAngles(), VectorCompare(), VL_FindAdjacentSurface(), VL_FloodLight(), VL_GenerateFacetFor4Points(), VL_LightmapMatrixFromPoints(), VL_LightSurfaceWithVolume(), VL_SmoothenLightmapEdges(), VL_TextureMatrixFromPoints(), VS_FindAdjacentSurface(), VS_FloodLight(), VS_GenerateFacetFor4Points(), VS_LightmapMatrixFromPoints(), VS_LightSurfaceWithVolume(), VS_SmoothenLightmapEdges(), VS_TextureMatrixFromPoints(), Winding_BaseForPlane(), Winding_TryMerge(), Winding_VectorIntersect(), WriteFloat(), WriteFloat2(), and WriteMapBrush().

double floor  ) 
 

Referenced by AllocateLightmapForSurface(), Brush_MakeSided(), Brush_MakeSidedCone(), Brush_MoveVertex_old1(), Brush_SnapPlanepts(), Brush_SnapToGrid(), CalcTerrainSize(), CG_AddParticleToScene(), ChopFaceByBrush(), CL_CgameSystemCalls(), CL_UISystemCalls(), CompareVert(), Drag_MouseMoved(), CXYWnd::DragDelta(), DrawSkyBox(), DrawSurfaceForSide(), EmitTerrainVerts(), EmitTerrainVerts2(), FillCloudBox(), HSVtoRGB(), CZWnd::OnMouseMove(), CMainFrame::OnViewCenter(), Patch_ApplyMatrix(), Q_rint(), R_LoadLightGrid(), R_NoiseGet4f(), R_SetupEntityLightingGrid(), RB_CalcScrollTexCoords(), Select_GetMid(), Select_SnapToGrid(), SelectFaceEdge(), SelectSplitPlaneNum(), SetFacetFilter(), SetTerrainTextures(), SetupGrid(), SubdivideDrawSurf(), SV_GameSystemCalls(), VectorSnap(), VL_GetFilter(), VL_LightmapMatrixFromPoints(), VL_LightSurfaceWithVolume(), VS_GetFilter(), VS_LightmapMatrixFromPoints(), VS_LightSurfaceWithVolume(), CXYWnd::XY_DrawBlockGrid(), CXYWnd::XY_DrawGrid(), CXYWnd::XY_ToGridPoint(), and Z_DrawGrid().

Heading  ) 
 

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:

History  ) 
 

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:

Instructions  ) 
 

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:

IsYeqX  ) 
 

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:

double log  ) 
 

Referenced by pow().

main  ) 
 

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 -