Listing 2: Example of a Common-Header program file


  1: /* ======== */
  2: /* xvsqrt.h */
  3: /* ======== */
  4: // After Cody & Waite and Plauger
  5: #include "xverfun.h"
  6: #define EXT_FUN xsqrt
  7: #define TST_FUN NAME(sqrt)
  8: // ----------------------
  9: // Natural logarithm of 2
 10: // ----------------------
 11: static const qfloat LOG2 = "0.69314718055994530941"
 12:                     "72321214581765680755";
 13: // -----------------------------------|
 14: // f1 - sqrt versus xsqrt over (.5, 1)|
 15: // ------------------a-----------------|
 16: qfloat f1 (qfloat x, qfloat &pzz)
 17: {
 18:     TYPE FunArg;
 19:
 20:     // Calculate Logarithmically Distributed Argument
 21:     FunArg = (TYPE)xtold(.5*xexp(x*LOG2));
 22:
 23:     pzz = EXT_FUN(FunArg);
 24:
 25:     return NAME(sqrt)(FunArg);
 26: }
 27: // ----------------------------------|
 28: // f2 - sqrt versus xsqrt over (1, 2)|
 29: // ----------------------------------|
 30: qfloat f2 (qfloat x, qfloat &pzz)
 31: {
 32:     TYPE FunArg;
 33:
 34:     // Calculate Logarithmically Distributed Argument
 35:     FunArg = (TYPE)xtold(xexp(x*LOG2));
 36:
 37:     pzz = EXT_FUN(FunArg);
 38:
 39:     return NAME(sqrt)(FunArg);
 40: }
 41: /* ===================================================== */
 42: /* main - Compares standard sqrt func with extended vers */
 43: /* ===================================================== */
 44: #define EXT_FUN_STR MAK_STR(EXT_FUN)
 45: #define MAK_STR(x)    STR_NAME(x)
 46: #define STR_NAME(x) #x
 47: #define TEST_SIZE 1000
 48: int
 49: main()
 50: {
 51:     const
 52:     char    *FunStr = MAK_STR(TST_FUN);
 53:     char     Label[128];
 54:     TYPE     TestArg, TestAns;
 55:     qfloat     HiLim, LoLim;
 56:     MACHAR_STRU  MachData;
 57: 
 58:     printf("Test of %s(x) vs. %s(x):\n",
 58:             FunStr, EXT_FUN_STR);
 59:     MachData = GetMachar();
 60: 
 61:     printf("There are %d Base %d Significant Digits\n",
 62:     MachData.FracDigs, MachData.Radix);
 63: 
 64:     HiLim = 1.0;
 65:     LoLim = (qfloat)1.0/(qfloat)MachData.Radix;
 66:     sprintf(Label, "Test %d: %s(x) for %d values in "
 67:            "(%.10LG, %.10LG)\n", 1,
 68:     FunStr, TEST_SIZE, xtold(LoLim), xtold(HiLim));
 69:     XVerFun(MachData, TEST_SIZE, LoLim, HiLim, &f1, Label);
 70: 
 71:     LoLim = HiLim;
 72:     HiLim = MachData.Radix;
 73:     sprintf(Label, "Test %d: %s(x) for %d values in "
 74:            "(%.10LG, %.10LG)\n", 2,
 75:     FunStr, TEST_SIZE, xtold(LoLim), xtold(HiLim));
 76:     XVerFun(MachData, TEST_SIZE, LoLim, HiLim, &f2, Label);
 77: 
 78:     printf("\nSPECIAL VALUES:\n");
 79: 
 80:     printf("\nThese calls should not "
 81:        "trigger error messages\n");
 82:     TestArg = (TYPE)0.0;
 83:     TestAns = NAME(sqrt)(TestArg);
 84:     if (TestAns == TestArg)
 85:     {
 86:     printf("\t%s(0) = 0 (Exactly)\n", FunStr);
 87:     }
 88:     else
 89:     {
 90:     printf("\t%s(0) Failed = %.20LG\n",
 91:         FunStr, (LDBL)TestAns);
 92:     }
 93:     TestArg = (TYPE)1.0;
 94:     TestAns = NAME(sqrt)(TestArg);
 95:     if (TestAns == TestArg)
 96:     {
 97:     printf("\t%s(1) = 1 (Exactly)\n", FunStr);
 98:     }
 99:     else
100:     {
101:     printf("\t%s(1) Failed = %.20LG\n", FunStr,
102:         (LDBL)TestAns);
103:     }
104:     printf("\n\tEpsNeg = %.20LG\n",
105:     (long double)MachData.EpsNeg);
106: 
107:     TestArg = (TYPE)1.0 - MachData.EpsNeg;
108:     TestAns = NAME(sqrt)(TestArg);
109:     if (TestAns == (TYPE) 1.0)
110:     {
111:     printf("\t%s(1 - EpsNeg) = 1 (Exactly)\n",
112:         FunStr);
113:     }
114:     else
115:     {
116:     printf("\t%s(1 - EpsNeg) = %.20LG\n",
117:         FunStr, (long double)TestAns);
118:     }
119:     printf("\n\tEps    = %.20LG\n",
120:     (long double)MachData.Eps);
121: 
122:     TestArg = (TYPE) 1.0 + MachData.Eps;
123:     TestAns = NAME(sqrt)(TestArg);
124:     if (TestAns == (TYPE) 1.0)
125:     {
126:     printf("\t%s(1 + Eps) = 1 (Exactly)\n",
127:         FunStr);
128:     }
129:     else
130:     {
131:     printf("\t%s(1 + Eps) = %.20LG\n",
132:         FunStr, (long double)TestAns);
133:     }
134: 
135:     TestArg = MachData.Min;
136:     printf("\n\tMin = %.20LG\n", (LDBL)TestArg);
137: 
138:     TestAns = NAME(sqrt)(TestArg);
139:     printf("\t%s(Min) = %.20LG\n", FunStr, (LDBL)TestAns);
140: 
141:     TestArg = MachData.Max;
142:     printf("\n\tMax = %.20LG\n", (LDBL)TestArg);
143: 
144:     TestAns = NAME(sqrt)(TestArg);
145:     printf("\t%s(Max) = %.20LG\n", FunStr, (LDBL)TestAns);
146: 
147:     {
148:     int    FailCt = 0;
149:     printf("\nTesting x = %s(x*x) for integral "
150:         "x in [1, %d]\n", FunStr, TEST_SIZE);
151:     for (TestArg = 1; TestArg <= TEST_SIZE; ++TestArg)
152:     {
153:         TestAns = NAME(sqrt)(TestArg*TestArg);
154:         if (TestArg != TestAns)
155:         {
156:            ++FailCt;
157:         }
158:     }
159:     printf("\n\tx = %s(x*x) failed %d out of %.Lf times\n",
160:         FunStr, FailCt, (LDBL)(TestArg-1));
161:     }
162: 
163:     printf("\nBOUNDARY VALUE:\n");
164:     printf("\tFinding Square Root of "
165:        "a Negative Number:\n");
166:     printf("\n\tThis call might trigger "
167:        "an error message\n");
168: 
169:     fflush(NULL);
170:     TestAns = NAME(sqrt)((TYPE)-1.0);
171: 
172:     fflush(NULL);
173:     printf("\tResult: %s(-1.0) = %LG\n",
174:     FunStr, (LDBL) TestAns);
175: 
176:     return (0);
177: }
/* End of File */