📄 paranoia.c
字号:
Y = One;
Y2 = Y;
Z1 = Radix - One;
FourD = Four * D;
do {
if (Y2 > Z2) {
Q = Radix;
Y1 = Y;
do {
X1 = FABS(Q + FLOOR(Half - Q / Y1) * Y1);
Q = Y1;
Y1 = X1;
} while ( ! (X1 <= Zero));
if (Q <= One) {
Z2 = Y2;
Z = Y;
}
}
Y = Y + Two;
X = X + Eight;
Y2 = Y2 + X;
if (Y2 >= FourD) Y2 = Y2 - FourD;
} while ( ! (Y >= D));
X8 = FourD - Z2;
Q = (X8 + Z * Z) / FourD;
X8 = X8 / Eight;
if (Q != FLOOR(Q)) Anomaly = True;
else {
Break = False;
do {
X = Z1 * Z;
X = X - FLOOR(X / Radix) * Radix;
if (X == One)
Break = True;
else
Z1 = Z1 - One;
} while ( ! (Break || (Z1 <= Zero)));
if ((Z1 <= Zero) && (! Break)) Anomaly = True;
else {
if (Z1 > RadixD2) Z1 = Z1 - Radix;
do {
NewD();
} while ( ! (U2 * D >= F9));
if (D * Radix - D != W - D) Anomaly = True;
else {
Z2 = D;
I = 0;
Y = D + (One + Z) * Half;
X = D + Z + Q;
SR3750();
Y = D + (One - Z) * Half + D;
X = D - Z + D;
X = X + Q + X;
SR3750();
NewD();
if (D - Z2 != W - Z2) Anomaly = True;
else {
Y = (D - Z2) + (Z2 + (One - Z) * Half);
X = (D - Z2) + (Z2 - Z + Q);
SR3750();
Y = (One + Z) * Half;
X = Q;
SR3750();
if (I == 0) Anomaly = True;
}
}
}
}
}
if ((I == 0) || Anomaly) {
BadCond(Failure, "Anomalous arithmetic with Integer < ");
printf("Radix^Precision = %.7e\n", W);
printf(" fails test whether sqrt rounds or chops.\n");
SqRWrng = True;
}
}
if (! Anomaly) {
if (! ((MinSqEr < Zero) || (MaxSqEr > Zero))) {
RSqrt = Rounded;
printf("Square root appears to be correctly rounded.\n");
}
else {
if ((MaxSqEr + U2 > U2 - Half) || (MinSqEr > Half)
|| (MinSqEr + Radix < Half)) SqRWrng = True;
else {
RSqrt = Chopped;
printf("Square root appears to be chopped.\n");
}
}
}
if (SqRWrng) {
printf("Square root is neither chopped nor correctly rounded.\n");
printf("Observed errors run from %.7e ", MinSqEr - Half);
printf("to %.7e ulps.\n", Half + MaxSqEr);
TstCond (Serious, MaxSqEr - MinSqEr < Radix * Radix,
"sqrt gets too many last digits wrong");
}
/*=============================================*/
Milestone = 90;
/*=============================================*/
Pause();
printf("Testing powers Z^i for small Integers Z and i.\n");
N = 0;
/* ... test powers of zero. */
I = 0;
Z = -Zero;
M = 3.0;
Break = False;
do {
X = One;
SR3980();
if (I <= 10) {
I = 1023;
SR3980();
}
if (Z == MinusOne) Break = True;
else {
Z = MinusOne;
PrintIfNPositive();
N = 0;
/* .. if(-1)^N is invalid, replace MinusOne by One. */
I = - 4;
}
} while ( ! Break);
PrintIfNPositive();
N1 = N;
N = 0;
Z = A1;
M = FLOOR(Two * LOG(W) / LOG(A1));
Break = False;
do {
X = Z;
I = 1;
SR3980();
if (Z == AInvrse) Break = True;
else Z = AInvrse;
} while ( ! (Break));
/*=============================================*/
Milestone = 100;
/*=============================================*/
/* Powers of Radix have been tested, */
/* next try a few primes */
M = NoTrials;
Z = Three;
do {
X = Z;
I = 1;
SR3980();
do {
Z = Z + Two;
} while ( Three * FLOOR(Z / Three) == Z );
} while ( Z < Eight * Three );
if (N > 0) {
printf("Errors like this may invalidate financial calculations\n");
printf("\tinvolving interest rates.\n");
}
PrintIfNPositive();
N += N1;
if (N == 0) printf("... no discrepancis found.\n");
if (N > 0) Pause();
else printf("\n");
/*=============================================*/
/*SPLIT
}
#include "paranoia.h"
part6(){
*/
Milestone = 110;
/*=============================================*/
printf("Seeking Underflow thresholds UfThold and E0.\n");
D = U1;
if (Precision != FLOOR(Precision)) {
D = BInvrse;
X = Precision;
do {
D = D * BInvrse;
X = X - One;
} while ( X > Zero);
}
Y = One;
Z = D;
/* ... D is power of 1/Radix < 1. */
do {
C = Y;
Y = Z;
Z = Y * Y;
} while ((Y > Z) && (Z + Z > Z));
Y = C;
Z = Y * D;
do {
C = Y;
Y = Z;
Z = Y * D;
} while ((Y > Z) && (Z + Z > Z));
if (Radix < Two) HInvrse = Two;
else HInvrse = Radix;
H = One / HInvrse;
/* ... 1/HInvrse == H == Min(1/Radix, 1/2) */
CInvrse = One / C;
E0 = C;
Z = E0 * H;
/* ...1/Radix^(BIG Integer) << 1 << CInvrse == 1/C */
do {
Y = E0;
E0 = Z;
Z = E0 * H;
} while ((E0 > Z) && (Z + Z > Z));
UfThold = E0;
E1 = Zero;
Q = Zero;
E9 = U2;
S = One + E9;
D = C * S;
if (D <= C) {
E9 = Radix * U2;
S = One + E9;
D = C * S;
if (D <= C) {
BadCond(Failure, "multiplication gets too many last digits wrong.\n");
Underflow = E0;
Y1 = Zero;
PseudoZero = Z;
Pause();
}
}
else {
Underflow = D;
PseudoZero = Underflow * H;
UfThold = Zero;
do {
Y1 = Underflow;
Underflow = PseudoZero;
if (E1 + E1 <= E1) {
Y2 = Underflow * HInvrse;
E1 = FABS(Y1 - Y2);
Q = Y1;
if ((UfThold == Zero) && (Y1 != Y2)) UfThold = Y1;
}
PseudoZero = PseudoZero * H;
} while ((Underflow > PseudoZero)
&& (PseudoZero + PseudoZero > PseudoZero));
}
/* Comment line 4530 .. 4560 */
if (PseudoZero != Zero) {
printf("\n");
Z = PseudoZero;
/* ... Test PseudoZero for "phoney- zero" violates */
/* ... PseudoZero < Underflow or PseudoZero < PseudoZero + PseudoZero
... */
if (PseudoZero <= Zero) {
BadCond(Failure, "Positive expressions can underflow to an\n");
printf("allegedly negative value\n");
printf("PseudoZero that prints out as: %g .\n", PseudoZero);
X = - PseudoZero;
if (X <= Zero) {
printf("But -PseudoZero, which should be\n");
printf("positive, isn't; it prints out as %g .\n", X);
}
}
else {
BadCond(Flaw, "Underflow can stick at an allegedly positive\n");
printf("value PseudoZero that prints out as %g .\n", PseudoZero);
}
TstPtUf();
}
/*=============================================*/
Milestone = 120;
/*=============================================*/
if (CInvrse * Y > CInvrse * Y1) {
S = H * S;
E0 = Underflow;
}
if (! ((E1 == Zero) || (E1 == E0))) {
BadCond(Defect, "");
if (E1 < E0) {
printf("Products underflow at a higher");
printf(" threshold than differences.\n");
if (PseudoZero == Zero)
E0 = E1;
}
else {
printf("Difference underflows at a higher");
printf(" threshold than products.\n");
}
}
printf("Smallest strictly positive number found is E0 = %g .\n", E0);
Z = E0;
TstPtUf();
Underflow = E0;
if (N == 1) Underflow = Y;
I = 4;
if (E1 == Zero) I = 3;
if (UfThold == Zero) I = I - 2;
UfNGrad = True;
switch (I) {
case 1:
UfThold = Underflow;
if ((CInvrse * Q) != ((CInvrse * Y) * S)) {
UfThold = Y;
BadCond(Failure, "Either accuracy deteriorates as numbers\n");
printf("approach a threshold = %.17e\n", UfThold);;
printf(" coming down from %.17e\n", C);
printf(" or else multiplication gets too many last digits wrong.\n");
}
Pause();
break;
case 2:
BadCond(Failure, "Underflow confuses Comparison, which alleges that\n");
printf("Q == Y while denying that |Q - Y| == 0; these values\n");
printf("print out as Q = %.17e, Y = %.17e .\n", Q, Y2);
printf ("|Q - Y| = %.17e .\n" , FABS(Q - Y2));
UfThold = Q;
break;
case 3:
X = X;
break;
case 4:
if ((Q == UfThold) && (E1 == E0)
&& (FABS( UfThold - E1 / E9) <= E1)) {
UfNGrad = False;
printf("Underflow is gradual; it incurs Absolute Error =\n");
printf("(roundoff in UfThold) < E0.\n");
Y = E0 * CInvrse;
Y = Y * (OneAndHalf + U2);
X = CInvrse * (One + U2);
Y = Y / X;
IEEE = (Y == E0);
}
}
if (UfNGrad) {
printf("\n");
sigsave = sigfpe;
if (setjmp(ovfl_buf)) {
printf("Underflow / UfThold failed!\n");
R = H + H;
}
else R = SQRT(Underflow / UfThold);
sigsave = 0;
if (R <= H) {
Z = R * UfThold;
X = Z * (One + R * H * (One + H));
}
else {
Z = UfThold;
X = Z * (One + H * H * (One + H));
}
if (! ((X == Z) || (X - Z != Zero))) {
BadCond(Flaw, "");
printf("X = %.17e\n\tis not equal to Z = %.17e .\n", X, Z);
Z9 = X - Z;
printf("yet X - Z yields %.17e .\n", Z9);
printf(" Should this NOT signal Underflow, ");
printf("this is a SERIOUS DEFECT\nthat causes ");
printf("confusion when innocent statements like\n");;
printf(" if (X == Z) ... else");
printf(" ... (f(X) - f(Z)) / (X - Z) ...\n");
printf("encounter Division by Zero although actually\n");
sigsave = sigfpe;
if (setjmp(ovfl_buf)) printf("X / Z fails!\n");
else printf("X / Z = 1 + %g .\n", (X / Z - Half) - Half);
sigsave = 0;
}
}
printf("The Underflow threshold is %.17e, %s\n", UfThold,
" below which");
printf("calculation may suffer larger Relative error than ");
printf("merely roundoff.\n");
Y2 = U1 * U1;
Y = Y2 * Y2;
Y2 = Y * U1;
if (Y2 <= UfThold) {
if (Y > E0) {
BadCond(Defect, "");
I = 5;
}
else {
BadCond(Serious, "");
I = 4;
}
printf("Range is too narrow; U1^%d Underflows.\n", I);
}
/*=============================================*/
/*SPLIT
}
#include "paranoia.h"
part7(){
*/
Milestone = 130;
/*=============================================*/
Y = - FLOOR(Half - TwoForty * LOG(UfThold) / LOG(HInvrse)) / TwoForty;
Y2 = Y + Y;
printf("Since underflow occurs below the threshold\n");
printf("UfThold = (%.17e) ^ (%.17e)\nonly underflow ", HInvrse, Y);
printf("should afflict the expression\n\t(%.17e) ^ (%.17e);\n", HInvrse, Y);
V9 = POW(HInvrse, Y2);
printf("actually calculating yields: %.17e .\n", V9);
if (! ((V9 >= Zero) && (V9 <= (Radix + Radix + E9) * UfThold))) {
BadCond(Serious, "this is not between 0 and underflow\n");
printf(" threshold = %.17e .\n", UfThold);
}
else if (! (V9 > UfThold * (One + E9)))
printf("This computed value is O.K.\n");
else {
BadCond(Defect, "this is not between 0 and underflow\n");
printf(" threshold = %.17e .\n", UfThold);
}
/*=============================================*/
Milestone = 140;
/*=============================================*/
printf("\n");
/* ...calculate Exp2 == exp(2) == 7.389056099... */
X = Zero;
I = 2;
Y = Two * Three;
Q = Zero;
N = 0;
do {
Z = X;
I = I + 1;
Y = Y / (I + I);
R = Y + Q;
X = Z + R;
Q = (Z - X) + R;
} while(X > Z);
Z = (OneAndHalf + One / Eight) + X / (OneAndHalf * ThirtyTwo);
X = Z * Z;
Exp2 = X * X;
X = F9;
Y = X - U1;
printf("Testing X^((X + 1) / (X - 1)) vs. exp(2) = %.17e as X -> 1.\n",
Exp2);
for(I = 1;;) {
Z = X - BInvrse;
Z = (X + One) / (Z - (One - BInvrse));
Q = POW(X, Z) - Exp2;
if (FABS(Q) > TwoForty * U2) {
N = 1;
V9 = (X - BInvrse) - (One - BInvrse);
BadCond(Defect, "Calculated");
printf(" %.17e for\n", POW(X,Z));
printf("\t(1 + (%.17e) ^ (%.17e);\n", V9, Z);
printf("\tdiffers from correct value by %.17e .\n", Q);
printf("\tThis much error may spoil financial\n");
printf("\tcalculations involving tiny interest rates.\n");
break;
}
else {
Z = (Y - X) * Two + Y;
X = Y;
Y = Z;
Z = One + (X - F9)*(X - F9);
if (Z > One && I < NoTrials) I++;
else {
if (X > One) {
if (N == 0)
printf("Accuracy seems adequate.\n");
break;
}
else {
X = One + U2;
Y = U2 + U2;
Y += X;
I = 1;
}
}
}
}
/*=============================================*/
Milestone = 150;
/*=============================================*/
printf("Testing powers Z^Q at four nearly extreme values.\n");
N = 0;
Z = A1;
Q = FLOOR(Half - LOG(C) / LOG(A1));
Break = False;
do {
X = CInvrse;
Y = POW(Z, Q);
IsYeqX();
Q = - Q;
X = C;
Y = POW(Z, Q);
IsYeqX();
if (Z < One) Break = True;
else Z = AInvrse;
} while ( ! (Break));
PrintIfNPositive();
if (N == 0) printf(" ... no discrepancies found.\n");
printf("\n");
/*=============================================*/
Milestone = 160;
/*=============================================*/
Pause();
printf("Searching for Overflow threshold:\n");
printf("This may generate an error.\n");
Y = - CInvrse;
V9 = HInvrse * Y;
sigsave = sigfpe;
if (setjmp(ovfl_buf)) { I = 0; V9 = Y; goto overflow; }
do {
V = Y;
Y = V9;
V9 = HInvrse * Y;
} while(V9 < Y);
I = 1;
overflow:
sigsave = 0;
Z = V9;
printf("Can `Z = -Y' overflow?\n");
printf("Trying it on Y = %.17e .\n", Y);
V9 = - Y;
V0 = V9;
if (V - Y == V + V0) printf("Seems O.K.\n");
else {
printf("finds a ");
BadCond(Flaw, "-(-Y) differs from Y.\n");
}
if (Z != Y) {
BadCond(Serious, "");
printf("overflow past %.17e\n\tshrinks to %.17e .\n", Y, Z);
}
if (I) {
Y = V * (HInvrse * U2 - HInvrse);
Z = Y + ((One - HInvrse) * U2) * V;
if (Z < V0) Y = Z;
if (Y < V0) V = Y;
if (V0 - V < V0) V = V0;
}
else {
V = Y * (HInvrse * U2 - HInvrse);
V = V + ((One - HInvrse) * U2) * Y;
}
printf("Overflow threshold is V = %.17e .\n", V);
if (I) printf("Overflow saturates at V0 = %.17e .\n", V0);
else printf("There is no saturation value because the system traps on overflow.\n");
V9 = V * One;
printf("No Overflow should be signaled for V * 1 = %.17e\n", V9);
V9 = V / One;
printf(" nor for V / 1 = %.17e .\n", V9);
printf("Any overflow signal separating this * from the one\n");
printf("above is a DEFECT.\n");
/*=============================================*/
Milestone = 170;
/*=============================================*/
if (!(-V < V && -V0 < V0 && -UfThold < V && UfThold < V)) {
BadCond(Failure, "Comparisons involving ");
printf("+-%g, +-%g\nand +-%g are confused by Overflow.",
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -