📄 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 + -