home *** CD-ROM | disk | FTP | other *** search
-
-
- /* CLOGS.C *****
- A group of programs in C, using the BDS-C floating point package
- as modified by LCC (FLOAT+44.*) and depending on the ability to
- insert null characters in a string available in BDS-C V 1.44.
- Four functions are handled:
- log10, exp10, expe, pi
- In addition, there is a service function exprange() which returns
- a false (00) if the exponent of a floating point variable is reaching
- near the end of the usable range.
- These are discussed in detail in CLOGS.DOC
-
- L. C. Calhoun
- 257 South Broadway
- Lebanon, Ohio 45036 513 day 433 7510 nite 932 4541
-
- */
-
-
- char *pi(result)
-
- /* result is a standard character array char result[5]; in calling
- program as used for floating point variables. The return is a pointer
- to result, and the value of pi stored in the result array in floating
- point */
-
- char *result;
- {
- char *piconst, *fpasg();
-
- piconst = "\171\356\207\144\2";
- return (fpasg(result,piconst) );
- }
-
- char *expe(result,xin)
-
- /* computes the base of the natural log "e" raised to the "x'th"
- power. Checks are made for out of range values and result is
- defaulted to 0, 1, or a large number as appropriate. There are
- no error flags. The arguments are floating point character
- arrays char result[5], x[5]; in calling program. Return is
- a pointer to result, and "e to the x" stored in result.
- */
-
- char *result, *xin;
- {
- char *zero, *one, *large, *coef[7], *eghty6, *meghty6;
- char intres[5], xint[5], x[5];
- char *fpmult(), *fpasg(), *fpdiv(), *fpchs();
- int signx, index, bigexp, smallexp, zeroin;
- int exprange();
-
- bigexp = smallexp = zeroin = 0;
-
- zero ="\0\0\0\0\0";
- one = "\0\0\0\100\1";
- large = "\0\0\0\100\175";
- eghty6 = "\0\0\0\126\7";
- meghty6 = "\0\0\0\252\7";
-
- coef[0] = "\0\0\0\100\1";
- coef[1] = "\140\326\377\177\376";
- coef[2] = "\130\373\3\100\374";
- coef[3] = "\200\1\352\124\370";
- coef[4] = "\351\253\362\131\364";
- coef[5] = "\21\213\32\133\357";
- coef[6] = "\371\330\260\134\354";
-
- /* preserve input datum */
- fpasg(x,xin);
-
- /* check for sign */
- if (x[3] < 128) /* positive */
- {signx = 1;
- }
- else
- {signx = 0;
- fpchs(x,x);
- }
-
- /* check for zero and out of range of fp var */
-
- /* check for zero and very small numbers */
- if ( ((x[4]>127) && (x[4]<226)) || ( (x[4]==0) &&
- (x[3]==0) && (x[2]==0) && (x[1]==0) && (x[0]==0) ) )
- zeroin = 1;
-
- /* check for very small exponent */
- if ( fpcomp(xin,meghty6) < 0)
- smallexp = 1;
-
- /* check for very large exponent */
- if ( fpcomp(x,eghty6) > 0 )
- bigexp = 1;
-
- /* now if small number or zero, result is one */
- /* now if big number and positive, result is large number */
- /* now if big number and negative, result is zero */
-
- if (zeroin) return (fpasg(result,one) );
- if (smallexp) return (fpasg(result,zero) );
- if (bigexp) return (fpasg(result,large) );
-
- /* all exceptions taken care of, so evaluate rest */
- fpasg(result,one);
- fpasg(xint,x);
- index = 1;
- while ( (index<=6) && exprange(xint) )
- {
- fpmult(intres,coef[index],xint);
- fpadd(result,result,intres);
- fpmult(xint,xint,x);
- index++;
- }
- /* now do the square square */
- fpmult(result,result,result);
- fpmult(result,result,result);
-
- /* now treat sign appropriately */
- if (signx) return (result);
- else
- {fpdiv(result,one,result);
- return (result);
- }
- }
-
- char *exp10(result,xin)
-
- /* similar to expe, except result returned is 10 raised to the x
- power the antilogarithm to base 10 */
-
- char *result, *xin;
- {
- char *zero, *ten, *one, *large, *thty8;
- char xint[5], *coef[7], intres[5], tenfac[5], x[5];
- int index, bigexp, smallexp, signx, tenpower;
- int exprange();
-
- bigexp = smallexp = 0;
-
- zero ="\0\0\0\0\0";
- one = "\0\0\0\100\1";
- large = "\0\0\0\100\175";
- ten = "\0\0\0\120\4";
- thty8 = "\0\0\0\114\6";
-
- coef[1] = "\65\264\256\111\1";
- coef[2] = "\0\14\330\124\0";
- coef[3] = "\0\46\354\100\377";
- coef[4] = "\24\140\107\115\375";
- coef[5] = "\242\304\361\155\372";
- coef[6] = "\361\143\246\134\371";
-
- /* preserve input datum */
- fpasg(x,xin);
-
- /* check for sign */
- if (x[3] < 128) /* positive */
- signx = 1;
- else /* negative */
- {signx = 0;
- fpchs(x,x);
- }
-
- /* check for very small or large numbers, check by exponent size */
- /* check for zero or small */
- if ( ((x[4]>127) && (x[4]<226)) || ( (x[4]==0) &&
- (x[3]==0) && (x[2]==0) && (x[1]==0) && (x[0]==0) ) )
- smallexp = 1;
- /* check for big number */
- if ( fpcomp(x,thty8) > 0)
- bigexp = 1;
-
- /* if value is small or zero, return 1 as with expe */
- /* if value is large and positive, return a large number */
- /* if value is large and negative, return zero */
-
- if (smallexp) return (fpasg(result,one) );
-
- if(bigexp && signx) return (fpasg(result,large) );
-
- if(bigexp && !signx) return (fpasg(result,zero) );
-
- /* now reduce range of x to between zero and one */
-
- tenpower = ftoit(x);
- itof(tenfac,tenpower);
- fpsub(x,x,tenfac);
- fpasg(tenfac,one);
- while (tenpower)
- {fpmult(tenfac,tenfac,ten);
- tenpower--;
- }
- /* now evaluate series */
- fpasg(result,one);
- fpasg(xint,x);
- index = 1;
-
- while ( (index <= 6) && exprange(xint) )
- {fpmult(intres,coef[index],xint);
- fpadd(result,result,intres);
- fpmult(xint,xint,x);
- index += 1;
- }
-
- /* now square result (note error in referenced article) */
- fpmult(result,result,result);
-
- /* now check sign and make proper return */
- fpmult(result,result,tenfac); /* scale back up */
-
- if (signx) return (result);
-
- else return ( fpdiv(result,one,result) );
- }
-
-
- char *log10(result,sign,xin)
-
- /* computes briggsian logarithm of x which is a char[5]
- floating point number. Return is logarithm in result[5],
- and sign pointed to by sign. The logarithm is taken
- of the magnitude, and sign information preserved
- as required by sign.
- */
- char *result, *xin;
- int *sign;
- {
- char *zero, *ten, *one, *large;
- char *sqrtten, x[5];
- char gamma[5], gamnum[5], gamden[5], *coef[5];
- char *half;
- char intres[5], gamint[5];
- int tenpower;
- int index, bigexp, smallexp, signx;
- int exprange();
-
- bigexp = smallexp = 0;
-
- zero ="\0\0\0\0\0";
- one = "\0\0\0\100\1";
- large = "\0\0\0\114\6";
- ten = "\0\0\0\120\4";
- half = "\0\0\0\100\0";
- sqrtten = "\304\145\61\145\2";
-
- coef[0] = "\362\6\56\157\0";
- coef[1] = "\30\346\21\112\377";
- coef[2] = "\100\55\344\132\376";
- coef[3] = "\106\73\244\140\375";
- coef[4] = "\174\5\367\141\376";
-
- /* preserve input variable */
- fpasg(x,xin);
-
- /* check for sign */
- if (x[3] < 128) /* positive */
- signx = 1;
- else /* negative */
- {signx = -1;
- fpchs(x,x);
- }
-
- /* check for very small or large numbers, check by exponent size */
- /* check for zero or small */
- if ( ((x[4]>127) && (x[4]<209)) || ( (x[4]==0) &&
- (x[3]==0) && (x[2]==0) && (x[1]==0) && (x[0]==0) ) )
- smallexp = 1;
- /* check for big number */
- if ( (x[4] >47) && (x[4] < 128) )
- bigexp = 1;
-
- /* if very small, return - a large number
- if very large, return + a large number */
-
- if (smallexp)
- {*sign = signx;
- return (fpchs(result,large) );
- }
- if (bigexp)
- {*sign = signx;
- return (fpasg(result,large) );
- }
- /* now bring into range 1 <= x < 10 */
- tenpower = 0;
- while ( fpcomp(x,ten) >= 0)
- {tenpower++;
- fpdiv(x,x,ten);
- }
- while ( fpcomp(x,one) < 0)
- {tenpower--;
- fpmult(x,x,ten);
- }
-
- /* now if exactly one, no need to evaluate */
- fpsub(gamnum,x,one);
- if (((gamnum[4]>127)&&(gamnum[4]<209)) || ((gamnum[0]==0) &&
- (gamnum[1]==0) && (gamnum[2] == 0) && (gamnum[3] == 0) ) )
- {*sign = signx;
- itof(result,tenpower);
- return (result);
- }
- /* now compute gamma for series */
-
- fpsub(gamnum,x,sqrtten);
- /* now check for size of numerator */
- if (((gamnum[4]>127)&&(gamnum[4]<209)) || ((gamnum[0]==0) &&
- (gamnum[1]==0) && (gamnum[2] == 0) && (gamnum[3] == 0) ) )
- {itof(result,tenpower);
- fpadd(result,result,half);
- *sign = signx;
- return (result);
- }
- fpadd(gamden,x,sqrtten);
- fpdiv(gamma,gamnum,gamden);
-
- /* now set up for series (use gamnum as gamma squared) */
- fpmult(gamnum,gamma,gamma);
- fpasg(gamint,gamma);
- index = 0;
- fpasg(result,half);
-
- /* now do series evaluation */
- while ( (index <= 4) && exprange(gamint) )
- {fpmult(intres,coef[index],gamint);
- fpadd(result,result,intres);
- fpmult(gamint,gamint,gamnum);
- index++;
- }
-
- /* now do correction for range reduction */
- if (tenpower != 0)
- {itof(intres,tenpower);
- fpadd(result,result,intres);
- }
-
- /* now clean up and return */
-
- *sign = signx;
- return (result);
- }
-
- int exprange(x)
-
- /* The input argument is a floating point function from BDS C which
- consists of an array of 5 character data. The function returns
- a 1 if the exponent is in the range of - 47 to + 47. Outside this
- range a value of 0 (false) is returned. This is a range of ten to
- plus or minus 14 power */
- char *x;
-
- { if ( ((x[4]<128) && (x[4]>47) ) || ((x[4]>127) && (x[4] < 209) ) )
- return (0);
- else return (1);
- }
- r+s├┘%!É n}╖╩7&!Æ ^#Vr+s! ═╥7&!₧ ^#Vr+sδ6 ├&├M&!₧ ^#Vr+s╒`inδßs├c&!₧ ^#Vr+s╒`inδßs├╕!₧ ~#fo6 δ!Ü 9∙δ┴╔├&├ì/┼! 9∙DM═Én}╖╩⌐&! ^#Vr+sδn&