📄 paranoia.c
字号:
printf("of significant digits but, by itself, this is a minor flaw.\n");
}
if (Radix == One)
printf("logarithmic encoding has precision characterized solely by U1.\n");
else printf("The number of significant digits of the Radix is %f .\n",
Precision);
TstCond (Serious, U2 * Nine * Nine * TwoForty < One,
"Precision worse than 5 decimal figures ");
/*=============================================*/
Milestone = 30;
/*=============================================*/
/* Test for extra-precise subepressions */
X = FABS(((Four / Three - One) - One / Four) * Three - One / Four);
do {
Z2 = X;
X = (One + (Half * Z2 + ThirtyTwo * Z2 * Z2)) - One;
} while ( ! ((Z2 <= X) || (X <= Zero)));
X = Y = Z = FABS((Three / Four - Two / Three) * Three - One / Four);
do {
Z1 = Z;
Z = (One / Two - ((One / Two - (Half * Z1 + ThirtyTwo * Z1 * Z1))
+ One / Two)) + One / Two;
} while ( ! ((Z1 <= Z) || (Z <= Zero)));
do {
do {
Y1 = Y;
Y = (Half - ((Half - (Half * Y1 + ThirtyTwo * Y1 * Y1)) + Half
)) + Half;
} while ( ! ((Y1 <= Y) || (Y <= Zero)));
X1 = X;
X = ((Half * X1 + ThirtyTwo * X1 * X1) - F9) + F9;
} while ( ! ((X1 <= X) || (X <= Zero)));
if ((X1 != Y1) || (X1 != Z1)) {
BadCond(Serious, "Disagreements among the values X1, Y1, Z1,\n");
printf("respectively %.7e, %.7e, %.7e,\n", X1, Y1, Z1);
printf("are symptoms of inconsistencies introduced\n");
printf("by extra-precise evaluation of arithmetic subexpressions.\n");
notify("Possibly some part of this");
if ((X1 == U1) || (Y1 == U1) || (Z1 == U1)) printf(
"That feature is not tested further by this program.\n") ;
}
else {
if ((Z1 != U1) || (Z2 != U2)) {
if ((Z1 >= U1) || (Z2 >= U2)) {
BadCond(Failure, "");
notify("Precision");
printf("\tU1 = %.7e, Z1 - U1 = %.7e\n",U1,Z1-U1);
printf("\tU2 = %.7e, Z2 - U2 = %.7e\n",U2,Z2-U2);
}
else {
if ((Z1 <= Zero) || (Z2 <= Zero)) {
printf("Because of unusual Radix = %f", Radix);
printf(", or exact rational arithmetic a result\n");
printf("Z1 = %.7e, or Z2 = %.7e ", Z1, Z2);
notify("of an\nextra-precision");
}
if (Z1 != Z2 || Z1 > Zero) {
X = Z1 / U1;
Y = Z2 / U2;
if (Y > X) X = Y;
Q = - LOG(X);
printf("Some subexpressions appear to be calculated extra\n");
printf("precisely with about %g extra B-digits, i.e.\n",
(Q / LOG(Radix)));
printf("roughly %g extra significant decimals.\n",
Q / LOG(10.));
}
printf("That feature is not tested further by this program.\n");
}
}
}
Pause();
/*=============================================*/
/*SPLIT
}
#include "paranoia.h"
part3(){
*/
Milestone = 35;
/*=============================================*/
if (Radix >= Two) {
X = W / (Radix * Radix);
Y = X + One;
Z = Y - X;
T = Z + U2;
X = T - Z;
TstCond (Failure, X == U2,
"Subtraction is not normalized X=Y,X+Z != Y+Z!");
if (X == U2) printf(
"Subtraction appears to be normalized, as it should be.");
}
printf("\nChecking for guard digit in *, /, and -.\n");
Y = F9 * One;
Z = One * F9;
X = F9 - Half;
Y = (Y - Half) - X;
Z = (Z - Half) - X;
X = One + U2;
T = X * Radix;
R = Radix * X;
X = T - Radix;
X = X - Radix * U2;
T = R - Radix;
T = T - Radix * U2;
X = X * (Radix - One);
T = T * (Radix - One);
if ((X == Zero) && (Y == Zero) && (Z == Zero) && (T == Zero)) GMult = Yes;
else {
GMult = No;
TstCond (Serious, False,
"* lacks a Guard Digit, so 1*X != X");
}
Z = Radix * U2;
X = One + Z;
Y = FABS((X + Z) - X * X) - U2;
X = One - U2;
Z = FABS((X - U2) - X * X) - U1;
TstCond (Failure, (Y <= Zero)
&& (Z <= Zero), "* gets too many final digits wrong.\n");
Y = One - U2;
X = One + U2;
Z = One / Y;
Y = Z - X;
X = One / Three;
Z = Three / Nine;
X = X - Z;
T = Nine / TwentySeven;
Z = Z - T;
TstCond(Defect, X == Zero && Y == Zero && Z == Zero,
"Division lacks a Guard Digit, so error can exceed 1 ulp\nor 1/3 and 3/9 and 9/27 may disagree");
Y = F9 / One;
X = F9 - Half;
Y = (Y - Half) - X;
X = One + U2;
T = X / One;
X = T - X;
if ((X == Zero) && (Y == Zero) && (Z == Zero)) GDiv = Yes;
else {
GDiv = No;
TstCond (Serious, False,
"Division lacks a Guard Digit, so X/1 != X");
}
X = One / (One + U2);
Y = X - Half - Half;
TstCond (Serious, Y < Zero,
"Computed value of 1/1.000..1 >= 1");
X = One - U2;
Y = One + Radix * U2;
Z = X * Radix;
T = Y * Radix;
R = Z / Radix;
StickyBit = T / Radix;
X = R - X;
Y = StickyBit - Y;
TstCond (Failure, X == Zero && Y == Zero,
"* and/or / gets too many last digits wrong");
Y = One - U1;
X = One - F9;
Y = One - Y;
T = Radix - U2;
Z = Radix - BMinusU2;
T = Radix - T;
if ((X == U1) && (Y == U1) && (Z == U2) && (T == U2)) GAddSub = Yes;
else {
GAddSub = No;
TstCond (Serious, False,
"- lacks Guard Digit, so cancellation is obscured");
}
if (F9 != One && F9 - One >= Zero) {
BadCond(Serious, "comparison alleges (1-U1) < 1 although\n");
printf(" subtraction yields (1-U1) - 1 = 0 , thereby vitiating\n");
printf(" such precautions against division by zero as\n");
printf(" ... if (X == 1.0) {.....} else {.../(X-1.0)...}\n");
}
if (GMult == Yes && GDiv == Yes && GAddSub == Yes) printf(
" *, /, and - appear to have guard digits, as they should.\n");
/*=============================================*/
Milestone = 40;
/*=============================================*/
Pause();
printf("Checking rounding on multiply, divide and add/subtract.\n");
RMult = Other;
RDiv = Other;
RAddSub = Other;
RadixD2 = Radix / Two;
A1 = Two;
Done = False;
do {
AInvrse = Radix;
do {
X = AInvrse;
AInvrse = AInvrse / A1;
} while ( ! (FLOOR(AInvrse) != AInvrse));
Done = (X == One) || (A1 > Three);
if (! Done) A1 = Nine + One;
} while ( ! (Done));
if (X == One) A1 = Radix;
AInvrse = One / A1;
X = A1;
Y = AInvrse;
Done = False;
do {
Z = X * Y - Half;
TstCond (Failure, Z == Half,
"X * (1/X) differs from 1");
Done = X == Radix;
X = Radix;
Y = One / X;
} while ( ! (Done));
Y2 = One + U2;
Y1 = One - U2;
X = OneAndHalf - U2;
Y = OneAndHalf + U2;
Z = (X - U2) * Y2;
T = Y * Y1;
Z = Z - X;
T = T - X;
X = X * Y2;
Y = (Y + U2) * Y1;
X = X - OneAndHalf;
Y = Y - OneAndHalf;
if ((X == Zero) && (Y == Zero) && (Z == Zero) && (T <= Zero)) {
X = (OneAndHalf + U2) * Y2;
Y = OneAndHalf - U2 - U2;
Z = OneAndHalf + U2 + U2;
T = (OneAndHalf - U2) * Y1;
X = X - (Z + U2);
StickyBit = Y * Y1;
S = Z * Y2;
T = T - Y;
Y = (U2 - Y) + StickyBit;
Z = S - (Z + U2 + U2);
StickyBit = (Y2 + U2) * Y1;
Y1 = Y2 * Y1;
StickyBit = StickyBit - Y2;
Y1 = Y1 - Half;
if ((X == Zero) && (Y == Zero) && (Z == Zero) && (T == Zero)
&& ( StickyBit == Zero) && (Y1 == Half)) {
RMult = Rounded;
printf("Multiplication appears to round correctly.\n");
}
else if ((X + U2 == Zero) && (Y < Zero) && (Z + U2 == Zero)
&& (T < Zero) && (StickyBit + U2 == Zero)
&& (Y1 < Half)) {
RMult = Chopped;
printf("Multiplication appears to chop.\n");
}
else printf("* is neither chopped nor correctly rounded.\n");
if ((RMult == Rounded) && (GMult == No)) notify("Multiplication");
}
else printf("* is neither chopped nor correctly rounded.\n");
/*=============================================*/
Milestone = 45;
/*=============================================*/
Y2 = One + U2;
Y1 = One - U2;
Z = OneAndHalf + U2 + U2;
X = Z / Y2;
T = OneAndHalf - U2 - U2;
Y = (T - U2) / Y1;
Z = (Z + U2) / Y2;
X = X - OneAndHalf;
Y = Y - T;
T = T / Y1;
Z = Z - (OneAndHalf + U2);
T = (U2 - OneAndHalf) + T;
if (! ((X > Zero) || (Y > Zero) || (Z > Zero) || (T > Zero))) {
X = OneAndHalf / Y2;
Y = OneAndHalf - U2;
Z = OneAndHalf + U2;
X = X - Y;
T = OneAndHalf / Y1;
Y = Y / Y1;
T = T - (Z + U2);
Y = Y - Z;
Z = Z / Y2;
Y1 = (Y2 + U2) / Y2;
Z = Z - OneAndHalf;
Y2 = Y1 - Y2;
Y1 = (F9 - U1) / F9;
if ((X == Zero) && (Y == Zero) && (Z == Zero) && (T == Zero)
&& (Y2 == Zero) && (Y2 == Zero)
&& (Y1 - Half == F9 - Half )) {
RDiv = Rounded;
printf("Division appears to round correctly.\n");
if (GDiv == No) notify("Division");
}
else if ((X < Zero) && (Y < Zero) && (Z < Zero) && (T < Zero)
&& (Y2 < Zero) && (Y1 - Half < F9 - Half)) {
RDiv = Chopped;
printf("Division appears to chop.\n");
}
}
if (RDiv == Other) printf("/ is neither chopped nor correctly rounded.\n");
BInvrse = One / Radix;
TstCond (Failure, (BInvrse * Radix - Half == Half),
"Radix * ( 1 / Radix ) differs from 1");
/*=============================================*/
/*SPLIT
}
#include "paranoia.h"
part4(){
*/
Milestone = 50;
/*=============================================*/
TstCond (Failure, ((F9 + U1) - Half == Half)
&& ((BMinusU2 + U2 ) - One == Radix - One),
"Incomplete carry-propagation in Addition");
X = One - U1 * U1;
Y = One + U2 * (One - U2);
Z = F9 - Half;
X = (X - Half) - Z;
Y = Y - One;
if ((X == Zero) && (Y == Zero)) {
RAddSub = Chopped;
printf("Add/Subtract appears to be chopped.\n");
}
if (GAddSub == Yes) {
X = (Half + U2) * U2;
Y = (Half - U2) * U2;
X = One + X;
Y = One + Y;
X = (One + U2) - X;
Y = One - Y;
if ((X == Zero) && (Y == Zero)) {
X = (Half + U2) * U1;
Y = (Half - U2) * U1;
X = One - X;
Y = One - Y;
X = F9 - X;
Y = One - Y;
if ((X == Zero) && (Y == Zero)) {
RAddSub = Rounded;
printf("Addition/Subtraction appears to round correctly.\n");
if (GAddSub == No) notify("Add/Subtract");
}
else printf("Addition/Subtraction neither rounds nor chops.\n");
}
else printf("Addition/Subtraction neither rounds nor chops.\n");
}
else printf("Addition/Subtraction neither rounds nor chops.\n");
S = One;
X = One + Half * (One + Half);
Y = (One + U2) * Half;
Z = X - Y;
T = Y - X;
StickyBit = Z + T;
if (StickyBit != Zero) {
S = Zero;
BadCond(Flaw, "(X - Y) + (Y - X) is non zero!\n");
}
StickyBit = Zero;
if ((GMult == Yes) && (GDiv == Yes) && (GAddSub == Yes)
&& (RMult == Rounded) && (RDiv == Rounded)
&& (RAddSub == Rounded) && (FLOOR(RadixD2) == RadixD2)) {
printf("Checking for sticky bit.\n");
X = (Half + U1) * U2;
Y = Half * U2;
Z = One + Y;
T = One + X;
if ((Z - One <= Zero) && (T - One >= U2)) {
Z = T + Y;
Y = Z - X;
if ((Z - T >= U2) && (Y - T == Zero)) {
X = (Half + U1) * U1;
Y = Half * U1;
Z = One - Y;
T = One - X;
if ((Z - One == Zero) && (T - F9 == Zero)) {
Z = (Half - U1) * U1;
T = F9 - Z;
Q = F9 - Y;
if ((T - F9 == Zero) && (F9 - U1 - Q == Zero)) {
Z = (One + U2) * OneAndHalf;
T = (OneAndHalf + U2) - Z + U2;
X = One + Half / Radix;
Y = One + Radix * U2;
Z = X * Y;
if (T == Zero && X + Radix * U2 - Z == Zero) {
if (Radix != Two) {
X = Two + U2;
Y = X / Two;
if ((Y - One == Zero)) StickyBit = S;
}
else StickyBit = S;
}
}
}
}
}
}
if (StickyBit == One) printf("Sticky bit apparently used correctly.\n");
else printf("Sticky bit used incorrectly or not at all.\n");
TstCond (Flaw, !(GMult == No || GDiv == No || GAddSub == No ||
RMult == Other || RDiv == Other || RAddSub == Other),
"lack(s) of guard digits or failure(s) to correctly round or chop\n(noted above) count as one flaw in the final tally below");
/*=============================================*/
Milestone = 60;
/*=============================================*/
printf("\n");
printf("Does Multiplication commute? ");
printf("Testing on %d random pairs.\n", NoTrials);
Random9 = SQRT(3.0);
Random1 = Third;
I = 1;
do {
X = Random();
Y = Random();
Z9 = Y * X;
Z = X * Y;
Z9 = Z - Z9;
I = I + 1;
} while ( ! ((I > NoTrials) || (Z9 != Zero)));
if (I == NoTrials) {
Random1 = One + Half / Three;
Random2 = (U2 + U1) + One;
Z = Random1 * Random2;
Y = Random2 * Random1;
Z9 = (One + Half / Three) * ((U2 + U1) + One) - (One + Half /
Three) * ((U2 + U1) + One);
}
if (! ((I == NoTrials) || (Z9 == Zero)))
BadCond(Defect, "X * Y == Y * X trial fails.\n");
else printf(" No failures found in %d integer pairs.\n", NoTrials);
/*=============================================*/
Milestone = 70;
/*=============================================*/
printf("\nRunning test of square root(x).\n");
TstCond (Failure, (Zero == SQRT(Zero))
&& (- Zero == SQRT(- Zero))
&& (One == SQRT(One)), "Square root of 0.0, -0.0 or 1.0 wrong");
MinSqEr = Zero;
MaxSqEr = Zero;
J = Zero;
X = Radix;
OneUlp = U2;
SqXMinX (Serious);
X = BInvrse;
OneUlp = BInvrse * U1;
SqXMinX (Serious);
X = U1;
OneUlp = U1 * U1;
SqXMinX (Serious);
if (J != Zero) Pause();
printf("Testing if sqrt(X * X) == X for %d Integers X.\n", NoTrials);
J = Zero;
X = Two;
Y = Radix;
if ((Radix != One)) do {
X = Y;
Y = Radix * Y;
} while ( ! ((Y - X >= NoTrials)));
OneUlp = X * U2;
I = 1;
while (I <= NoTrials) {
X = X + One;
SqXMinX (Defect);
if (J > Zero) break;
I = I + 1;
}
printf("Test for sqrt monotonicity.\n");
I = - 1;
X = BMinusU2;
Y = Radix;
Z = Radix + Radix * U2;
NotMonot = False;
Monot = False;
while ( ! (NotMonot || Monot)) {
I = I + 1;
X = SQRT(X);
Q = SQRT(Y);
Z = SQRT(Z);
if ((X > Q) || (Q > Z)) NotMonot = True;
else {
Q = FLOOR(Q + Half);
if ((I > 0) || (Radix == Q * Q)) Monot = True;
else if (I > 0) {
if (I > 1) Monot = True;
else {
Y = Y * BInvrse;
X = Y - U1;
Z = Y + U1;
}
}
else {
Y = Q;
X = Y - U2;
Z = Y + U2;
}
}
}
if (Monot) printf("sqrt has passed a test for Monotonicity.\n");
else {
BadCond(Defect, "");
printf("sqrt(X) is non-monotonic for X near %.7e .\n", Y);
}
/*=============================================*/
/*SPLIT
}
#include "paranoia.h"
part5(){
*/
Milestone = 80;
/*=============================================*/
MinSqEr = MinSqEr + Half;
MaxSqEr = MaxSqEr - Half;
Y = (SQRT(One + U2) - One) / U2;
SqEr = (Y - One) + U2 / Eight;
if (SqEr > MaxSqEr) MaxSqEr = SqEr;
SqEr = Y + U2 / Eight;
if (SqEr < MinSqEr) MinSqEr = SqEr;
Y = ((SQRT(F9) - U2) - (One - U2)) / U1;
SqEr = Y + U1 / Eight;
if (SqEr > MaxSqEr) MaxSqEr = SqEr;
SqEr = (Y + One) + U1 / Eight;
if (SqEr < MinSqEr) MinSqEr = SqEr;
OneUlp = U2;
X = OneUlp;
for( Indx = 1; Indx <= 3; ++Indx) {
Y = SQRT((X + U1 + X) + F9);
Y = ((Y - U2) - ((One - U2) + X)) / OneUlp;
Z = ((U1 - X) + F9) * Half * X * X / OneUlp;
SqEr = (Y + Half) + Z;
if (SqEr < MinSqEr) MinSqEr = SqEr;
SqEr = (Y - Half) + Z;
if (SqEr > MaxSqEr) MaxSqEr = SqEr;
if (((Indx == 1) || (Indx == 3)))
X = OneUlp * Sign (X) * FLOOR(Eight / (Nine * SQRT(OneUlp)));
else {
OneUlp = U1;
X = - OneUlp;
}
}
/*=============================================*/
Milestone = 85;
/*=============================================*/
SqRWrng = False;
Anomaly = False;
RSqrt = Other; /* ~dgh */
if (Radix != One) {
printf("Testing whether sqrt is rounded or chopped.\n");
D = FLOOR(Half + POW(Radix, One + Precision - FLOOR(Precision)));
/* ... == Radix^(1 + fract) if (Precision == Integer + fract. */
X = D / Radix;
Y = D / A1;
if ((X != FLOOR(X)) || (Y != FLOOR(Y))) {
Anomaly = True;
}
else {
X = Zero;
Z2 = X;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -