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