1 #include "paranoia.h"
part2(VOID)2 void part2(VOID){
3 	Milestone = 10;
4 	/*=============================================*/
5 	TstCond (Failure, (Nine == Three * Three)
6 		   && (TwentySeven == Nine * Three) && (Eight == Four + Four)
7 		   && (ThirtyTwo == Eight * Four)
8 		   && (ThirtyTwo - TwentySeven - Four - One == Zero),
9 		   "9 != 3*3, 27 != 9*3, 32 != 8*4, or 32-27-4-1 != 0");
10 	TstCond (Failure, (Five == Four + One) &&
11 			(TwoForty == Four * Five * Three * Four)
12 		   && (TwoForty / Three - Four * Four * Five == Zero)
13 		   && ( TwoForty / Four - Five * Three * Four == Zero)
14 		   && ( TwoForty / Five - Four * Three * Four == Zero),
15 		  "5 != 4+1, 240/3 != 80, 240/4 != 60, or 240/5 != 48");
16 	if (ErrCnt[Failure] == 0) {
17 		printf("-1, 0, 1/2, 1, 2, 3, 4, 5, 9, 27, 32 & 240 are O.K.\n");
18 		printf("\n");
19 		}
20 	printf("Searching for Radix and Precision.\n");
21 	W = One;
22 	do  {
23 		W = W + W;
24 		Y = W + One;
25 		Z = Y - W;
26 		Y = Z - One;
27 		} while (MinusOne + FABS(Y) < Zero);
28 	/*.. now W is just big enough that |((W+1)-W)-1| >= 1 ...*/
29 	Precision = Zero;
30 	Y = One;
31 	do  {
32 		Radix = W + Y;
33 		Y = Y + Y;
34 		Radix = Radix - W;
35 		} while ( Radix == Zero);
36 	if (Radix < Two) Radix = One;
37 	printf("Radix = %f .\n", Radix);
38 	if (Radix != 1) {
39 		W = One;
40 		do  {
41 			Precision = Precision + One;
42 			W = W * Radix;
43 			Y = W + One;
44 			} while ((Y - W) == One);
45 		}
46 	/*... now W == Radix^Precision is barely too big to satisfy (W+1)-W == 1
47 			                              ...*/
48 	U1 = One / W;
49 	U2 = Radix * U1;
50 	printf("Closest relative separation found is U1 = %.7e .\n\n", U1);
51 	printf("Recalculating radix and precision\n ");
52 
53 	/*save old values*/
54 	E0 = Radix;
55 	E1 = U1;
56 	E9 = U2;
57 	E3 = Precision;
58 
59 	X = Four / Three;
60 	Third = X - One;
61 	F6 = Half - Third;
62 	X = F6 + F6;
63 	X = FABS(X - Third);
64 	if (X < U2) X = U2;
65 
66 	/*... now X = (unknown no.) ulps of 1+...*/
67 	do  {
68 		U2 = X;
69 		Y = Half * U2 + ThirtyTwo * U2 * U2;
70 		Y = One + Y;
71 		X = Y - One;
72 		} while ( ! ((U2 <= X) || (X <= Zero)));
73 
74 	/*... now U2 == 1 ulp of 1 + ... */
75 	X = Two / Three;
76 	F6 = X - Half;
77 	Third = F6 + F6;
78 	X = Third - Half;
79 	X = FABS(X + F6);
80 	if (X < U1) X = U1;
81 
82 	/*... now  X == (unknown no.) ulps of 1 -... */
83 	do  {
84 		U1 = X;
85 		Y = Half * U1 + ThirtyTwo * U1 * U1;
86 		Y = Half - Y;
87 		X = Half + Y;
88 		Y = Half - X;
89 		X = Half + Y;
90 		} while ( ! ((U1 <= X) || (X <= Zero)));
91 	/*... now U1 == 1 ulp of 1 - ... */
92 	if (U1 == E1) printf("confirms closest relative separation U1 .\n");
93 	else printf("gets better closest relative separation U1 = %.7e .\n", U1);
94 	W = One / U1;
95 	F9 = (Half - U1) + Half;
96 	Radix = FLOOR(0.01 + U2 / U1);
97 	if (Radix == E0) printf("Radix confirmed.\n");
98 	else printf("MYSTERY: recalculated Radix = %.7e .\n", Radix);
99 	TstCond (Defect, Radix <= Eight + Eight,
100 		   "Radix is too big: roundoff problems");
101 	TstCond (Flaw, (Radix == Two) || (Radix == 10)
102 		   || (Radix == One), "Radix is not as good as 2 or 10");
103 	/*=============================================*/
104 	Milestone = 20;
105 	/*=============================================*/
106 	TstCond (Failure, F9 - Half < Half,
107 		   "(1-U1)-1/2 < 1/2 is FALSE, prog. fails?");
108 	X = F9;
109 	I = 1;
110 	Y = X - Half;
111 	Z = Y - Half;
112 	TstCond (Failure, (X != One)
113 		   || (Z == Zero), "Comparison is fuzzy,X=1 but X-1/2-1/2 != 0");
114 	X = One + U2;
115 	I = 0;
116 	/*=============================================*/
117 	Milestone = 25;
118 	/*=============================================*/
119 	/*... BMinusU2 = nextafter(Radix, 0) */
120 	BMinusU2 = Radix - One;
121 	BMinusU2 = (BMinusU2 - U2) + One;
122 	/* Purify Integers */
123 	if (Radix != One)  {
124 		X = - TwoForty * LOG(U1) / LOG(Radix);
125 		Y = FLOOR(Half + X);
126 		if (FABS(X - Y) * Four < One) X = Y;
127 		Precision = X / TwoForty;
128 		Y = FLOOR(Half + Precision);
129 		if (FABS(Precision - Y) * TwoForty < Half) Precision = Y;
130 		}
131 	if ((Precision != FLOOR(Precision)) || (Radix == One)) {
132 		printf("Precision cannot be characterized by an Integer number\n");
133 		printf("of significant digits but, by itself, this is a minor flaw.\n");
134 		}
135 	if (Radix == One)
136 		printf("logarithmic encoding has precision characterized solely by U1.\n");
137 	else printf("The number of significant digits of the Radix is %f .\n",
138 			Precision);
139 	TstCond (Serious, U2 * Nine * Nine * TwoForty < One,
140 		   "Precision worse than 5 decimal figures  ");
141 	/*=============================================*/
142 	Milestone = 30;
143 	/*=============================================*/
144 	/* Test for extra-precise subepressions */
145 	X = FABS(((Four / Three - One) - One / Four) * Three - One / Four);
146 	do  {
147 		Z2 = X;
148 		X = (One + (Half * Z2 + ThirtyTwo * Z2 * Z2)) - One;
149 		} while ( ! ((Z2 <= X) || (X <= Zero)));
150 	X = Y = Z = FABS((Three / Four - Two / Three) * Three - One / Four);
151 	do  {
152 		Z1 = Z;
153 		Z = (One / Two - ((One / Two - (Half * Z1 + ThirtyTwo * Z1 * Z1))
154 			+ One / Two)) + One / Two;
155 		} while ( ! ((Z1 <= Z) || (Z <= Zero)));
156 	do  {
157 		do  {
158 			Y1 = Y;
159 			Y = (Half - ((Half - (Half * Y1 + ThirtyTwo * Y1 * Y1)) + Half
160 				)) + Half;
161 			} while ( ! ((Y1 <= Y) || (Y <= Zero)));
162 		X1 = X;
163 		X = ((Half * X1 + ThirtyTwo * X1 * X1) - F9) + F9;
164 		} while ( ! ((X1 <= X) || (X <= Zero)));
165 	if ((X1 != Y1) || (X1 != Z1)) {
166 		BadCond(Serious, "Disagreements among the values X1, Y1, Z1,\n");
167 		printf("respectively  %.7e,  %.7e,  %.7e,\n", X1, Y1, Z1);
168 		printf("are symptoms of inconsistencies introduced\n");
169 		printf("by extra-precise evaluation of arithmetic subexpressions.\n");
170 		notify("Possibly some part of this");
171 		if ((X1 == U1) || (Y1 == U1) || (Z1 == U1))  printf(
172 			"That feature is not tested further by this program.\n") ;
173 		}
174 	else  {
175 		if ((Z1 != U1) || (Z2 != U2)) {
176 			if ((Z1 >= U1) || (Z2 >= U2)) {
177 				BadCond(Failure, "");
178 				notify("Precision");
179 				printf("\tU1 = %.7e, Z1 - U1 = %.7e\n",U1,Z1-U1);
180 				printf("\tU2 = %.7e, Z2 - U2 = %.7e\n",U2,Z2-U2);
181 				}
182 			else {
183 				if ((Z1 <= Zero) || (Z2 <= Zero)) {
184 					printf("Because of unusual Radix = %f", Radix);
185 					printf(", or exact rational arithmetic a result\n");
186 					printf("Z1 = %.7e, or Z2 = %.7e ", Z1, Z2);
187 					notify("of an\nextra-precision");
188 					}
189 				if (Z1 != Z2 || Z1 > Zero) {
190 					X = Z1 / U1;
191 					Y = Z2 / U2;
192 					if (Y > X) X = Y;
193 					Q = - LOG(X);
194 					printf("Some subexpressions appear to be calculated extra\n");
195 					printf("precisely with about %g extra B-digits, i.e.\n",
196 						(Q / LOG(Radix)));
197 					printf("roughly %g extra significant decimals.\n",
198 						Q / LOG(10.));
199 					}
200 				printf("That feature is not tested further by this program.\n");
201 				}
202 			}
203 		}
204 	Pause();
205 	/*=============================================*/
206 	}
207