home *** CD-ROM | disk | FTP | other *** search
/ Oakland CPM Archive / oakcpm.iso / sigm / vol097 / mathpack.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1984-04-29  |  18.2 KB  |  913 lines

  1. { for future debugging efforts }{$e+}
  2. PROGRAM mathpack;
  3.  
  4. CONST  dpmax=6; {upper limit controled by carry in simm}
  5.        digmax=dpmax*2;
  6.  
  7. TYPE  flt = RECORD
  8.             exp:integer; {exp=exponent*2 (+1 if neg mant.)}
  9.             dp : ARRAY [1..dpmax] OF 0..99
  10.           END;
  11.       $string255= STRING 255;
  12.       $string0  = STRING 0;
  13.       byte= 0..255; {short integer}
  14.  
  15. VAR   m,n: integer;
  16.       i,j,k: byte;
  17.       u,v,w: flt;
  18.       i$,o$: STRING 127;
  19.       error$: $string255;
  20. message$: STRING 40; 
  21. FUNCTION length (x: $string255):integer;external;
  22. FUNCTION index (x,y: $string255):integer;external;
  23. PROCEDURE setlength (VAR x: $string0; y:integer);external;
  24.  
  25. {it is intended that parts of this program would become}
  26. {included files [or externals] for pascalZ programs}
  27. {requiring number formats more powerful than real or}
  28. {fixed. division is slow for large number of digits}
  29.  
  30.  
  31.  
  32. PROCEDURE errortrap (errnum: integer;message$: $string255);
  33.  
  34. {error recovery or unrecoverable error exit module}
  35.  
  36. VAR  u,v: integer;
  37.  
  38. BEGIN
  39. writeln ('ERROR TRAP FUNCTION');
  40. writeln ( message$ );
  41. writeln ( error$ );
  42. writeln; 
  43. CASE errnum OF
  44.      0:BEGIN
  45.        writeln ('PROGRAM CANNOT RECOVER!');
  46.        u:=2;
  47.        v:=u-2;
  48.        u:=u DIV v
  49.        END;
  50.      1:writeln ('no action taken');
  51.      2:writeln ('maximum value returned');
  52.      3:writeln ('zero value returned');
  53.      4:writeln ('null string returned');
  54.      5:writeln ('blank char returned');
  55.      ELSE:BEGIN
  56.           writeln ('undefined error number = ',errnum );
  57.           errortrap (0,'undefined error handling')
  58.           END {else}
  59.    END; {case}
  60. END; {errortrap}
  61.  
  62. {returns 0 for positive and 1 for negative}
  63. FUNCTION signdig (u:flt):integer;
  64.  
  65. BEGIN
  66. signdig:=(abs(u.exp))MOD 2;
  67. END; {signdig}
  68.  
  69. {returns base 10 exponent of type flt}
  70. FUNCTION expvalue (u:flt):integer;
  71.  
  72. VAR  i:integer;
  73.  
  74. BEGIN
  75. IF ODD(u.exp)
  76. THEN i:=(u.exp-1) DIV 2
  77. ELSE i:=u.exp DIV 2;
  78. expvalue :=i
  79. END; {expvalue}
  80.  
  81. {integer to flt conversion and intitalization}
  82. PROCEDURE setF (n: integer; VAR u:flt);
  83.  
  84. VAR i: byte;
  85.     D: ARRAY [1..5] OF 0..9;
  86.  
  87. BEGIN
  88. u.exp:=0;
  89. FOR i:=1 TO dpmax DO
  90.      u.dp[i]:=0;
  91. IF NOT (n=0)
  92. THEN BEGIN
  93.      IF n<0
  94.      THEN u.exp:=1;
  95.      n:=abs(n);
  96.      D[1]:=n DIV 10000;
  97.      D[2]:=n MOD 10000 DIV 1000;
  98.      D[3]:=n MOD 1000 DIV 100;
  99.      D[4]:=n MOD 100 DIV 10;
  100.      D[5]:=n MOD 10;
  101.      IF D[1]=0
  102.      THEN IF D[2]=0
  103.           THEN IF D[3]=0
  104.                THEN IF D[4]=0
  105.                     THEN BEGIN
  106.                          u.dp[1]:=D[5]*10
  107.                          END
  108.                     ELSE BEGIN
  109.                          u.dp[1]:=D[4]*10+D[5];
  110.                          u.exp:=u.exp+2
  111.                          END
  112.                ELSE BEGIN
  113.                     u.dp[1]:= D[3]*10+D[4];
  114.                     u.dp[2]:= D[5]*10;
  115.                     u.exp:=u.exp+4
  116.                     END
  117.           ELSE BEGIN
  118.                u.dp[1]:=D[2]*10+D[3];
  119.                u.dp[2]:=D[4]*10+D[5];
  120.                u.exp:=u.exp+6
  121.                END
  122.      ELSE BEGIN
  123.           u.dp[1]:=D[1]*10+D[2];
  124.           u.dp[2]:=D[3]*10+D[4];
  125.           u.dp[3]:=D[5]*10;
  126.           u.exp:=u.exp+8
  127.           END
  128.      END {then}
  129. END; {setF}
  130.  
  131. {tests digits and not exponent}
  132. FUNCTION ztest (u: flt):boolean;
  133.  
  134. VAR i: byte;
  135.     value: boolean;
  136.  
  137. BEGIN
  138. value:= true;
  139. i:= 1;
  140. WHILE value AND (i<=dpmax) DO
  141.      IF NOT (u.dp[i]=0)
  142.      THEN value:=false
  143.      ELSE i:=i+1;
  144. END; {ztest}
  145.  
  146. {early version of Ftostr used to debug modules}
  147. PROCEDURE dispF (u: flt);
  148.  
  149. VAR i,j,k: integer;
  150.  
  151. BEGIN
  152. i:= u.exp MOD 2;
  153. IF ODD(u.exp)
  154. THEN write ('-')
  155. ELSE write (' ');
  156. i:=u.dp[1] DIV 10;
  157. write (i:1);
  158. write ('.');
  159. i:=u.dp[1] MOD 10;
  160. write (i:1);
  161. FOR i:=2 TO dpmax DO
  162.      BEGIN
  163.      j:=u.dp[i] DIV 10;
  164.      write (j:1);
  165.      j:=u.dp[i] MOD 10;
  166.      write (j:1)
  167.      END;
  168. write ('E');
  169. i:=expvalue(u);
  170. IF i<0
  171. THEN BEGIN
  172.      write ('-');
  173.      i:=abs(i)
  174.      END;
  175. IF i=0
  176. THEN write ('0')
  177. ELSE BEGIN
  178.      IF i>999
  179.      THEN IF i>9999
  180.           THEN write (i:5)
  181.           ELSE write (i:4)
  182.      ELSE IF i>99
  183.           THEN write (i:3)
  184.           ELSE IF i>9
  185.                THEN write (i:2)
  186.                ELSE write (i:1)
  187.      END; {else}
  188. writeln
  189. END; {dispF}
  190.  
  191. {this test is for algerbraic greater than}
  192. FUNCTION gtest (u,v: flt):boolean;
  193.  
  194. VAR  i:byte;
  195.      value,decided: boolean;
  196.  
  197. BEGIN
  198. if ztest(u)
  199. then u.exp:=0;
  200. if ztest(v)
  201. then v.exp:=0;
  202. value:= false;
  203. IF (ODD(u.exp)=ODD(v.exp))
  204. THEN BEGIN
  205.      IF ((u.exp DIV 2)=(v.exp DIV 2))
  206.      THEN BEGIN
  207.           i:=1;
  208.           decided:= false;
  209.           WHILE NOT decided AND (i<=dpmax) DO
  210.                BEGIN
  211.                IF u.dp[i]=v.dp[i]
  212.                THEN i:=i+1
  213.                ELSE BEGIN
  214.                     decided:= true;
  215.                     IF u.dp[i]>v.dp[i]
  216.                     THEN value:=true
  217.                     END
  218.                END {while}
  219.           END {then}
  220.      ELSE IF ((u.exp DIV 2)>(v.exp DIV 2))
  221.           THEN value:= true;
  222.      IF ODD(u.exp)
  223.      THEN value:= NOT(value)
  224.      END
  225. ELSE IF ODD(v.exp)
  226.      THEN value:=true;
  227. gtest:=value
  228. END; {gtest}
  229.  
  230. {fixes exponent for numbers that might be zero}
  231. procedure zfix( var u:flt);
  232.  
  233. begin
  234. if ztest(u)
  235. then u.exp:=0
  236. end; {zfix}
  237.  
  238. {tests sign of mant. }
  239. FUNCTION ntest (u:flt):boolean;
  240.  
  241. BEGIN
  242. IF ODD(u.exp)
  243. THEN ntest:= true
  244. ELSE ntest:= false
  245. END; {ntest}
  246.  
  247. {digit shift with exp. correction remains almost the}
  248. {same number except last digit is lost}
  249. PROCEDURE sr1 (VAR u:flt);
  250.  
  251. VAR  i: byte;
  252.  
  253. BEGIN
  254. FOR i:=dpmax DOWNTO 2 DO
  255.      u.dp[i]:=u.dp[i] DIV 10+((u.dp[i-1] MOD 10)*10);
  256. u.dp[1]:=u.dp[1] DIV 10;
  257. u.exp:=u.exp+2
  258. END; {sr1}
  259.  
  260. {this time first digit is lost}
  261. PROCEDURE sl1 (VAR u:flt);
  262.  
  263. VAR  i:byte;
  264.  
  265. BEGIN
  266. FOR i:=1 TO dpmax-1 DO
  267.      u.dp[i]:=u.dp[i] MOD 10 *10+(u.dp[i+1] DIV 10);
  268. u.dp[dpmax]:= u.dp[dpmax] MOD 10 *10;
  269. u.exp:=u.exp-2
  270. END; {sl1}
  271.  
  272. {sr1,sl1,sle and sre are used by shift}
  273.  
  274. PROCEDURE sle (n: integer; VAR u: flt);
  275.  
  276. VAR  i: byte;
  277.  
  278. BEGIN
  279. n:=abs(n) DIV 2;
  280. FOR i:=1 TO dpmax DO
  281.      IF (i+n)>dpmax
  282.      THEN u.dp[i]:=0
  283.      ELSE U.dp[i]:=u.dp[i+n];
  284. u.exp:=u.exp-(4*n)
  285. END; {sl2n}
  286.  
  287. PROCEDURE sre (n: integer; VAR u: flt);
  288.  
  289. VAR  i:byte;
  290.  
  291. BEGIN
  292. n:=n DIV 2;
  293. FOR i:= dpmax DOWNTO 1 DO
  294.      IF (i-n)<1
  295.      THEN u.dp[i]:=0
  296.      ELSE u.dp[i]:=u.dp[i-n];
  297. u.exp:=u.exp+(4*n)
  298. END; {sre}
  299.  
  300. {handels shifts of flt numbers }
  301. {positive n is to the right}
  302. PROCEDURE shift (n: integer; VAR u: flt);
  303.  
  304. BEGIN
  305. IF NOT (n=0)
  306. THEN IF n>(digmax-1)
  307.      THEN setF (0,u)
  308.      ELSE IF n>(0-digmax)
  309.           THEN IF n<0
  310.                THEN IF n=(-1)
  311.                     THEN sl1(u)
  312.                     ELSE IF ODD(n)
  313.                          THEN BEGIN
  314.                               sl1(u);
  315.                               n:=n+1;
  316.                               sle(n,u)
  317.                               END
  318.                          ELSE sle(n,u)
  319.                ELSE IF n=1
  320.                     THEN sr1(u)
  321.                     ELSE IF ODD(n)
  322.                          THEN BEGIN
  323.                               sr1(u);
  324.                               n:=n-1;
  325.                               sre(n,u)
  326.                               END
  327.                          ELSE sre(n,u)
  328.           ELSE setF(0,u);
  329. END; {shift}
  330.  
  331. {chops of digits to left of decimal point}
  332. FUNCTION ipart (u:flt):flt;
  333.  
  334. VAR  n:byte;
  335.      v:flt;
  336.  
  337. BEGIN
  338. IF u.exp>=digmax
  339. THEN v:=u
  340. ELSE  IF u.exp<0
  341.       THEN setf(0,v)
  342.       ELSE BEGIN
  343.            n:=digmax-1-(u.exp DIV 2);
  344.            v:=u;
  345.            shift(n,v);
  346.            n:=0-n;
  347.            shift (n,v);
  348.            END;
  349. ipart:=v
  350. END; {ipart}
  351.  
  352. {prevents zeros from being the first digit}
  353. PROCEDURE slar (VAR u: flt);
  354.  
  355. VAR  i:byte;
  356.      notdone: boolean;
  357.      n: integer;
  358.  
  359. BEGIN
  360. n:=0;
  361. i:=1;
  362. notdone:=true;
  363. WHILE notdone AND (i-1<dpmax) DO
  364.      IF u.dp[i]=0
  365.      THEN BEGIN
  366.           n:=n+2;
  367.           i:=i+1
  368.           END
  369.      ELSE BEGIN
  370.           notdone:=false;
  371.           IF u.dp[i]<10
  372.           THEN n:=n+1
  373.           END;
  374. n:=0-n;
  375. shift (n,u)
  376. END; {slar}
  377.  
  378. {chops off digits to left of decimal point}
  379. FUNCTION fpart (u:flt):flt;
  380.  
  381. VAR  n:integer;
  382.      v:flt;
  383.  
  384. BEGIN
  385. IF u.exp>=digmax
  386. THEN setF (0,v)
  387. ELSE BEGIN
  388.      v:=u;
  389.      IF u.exp>(0-1)
  390.      THEN BEGIN
  391.           n:=0-1-(u.exp DIV 2);
  392.           shift (n,v)
  393.           END
  394.      END {else}
  395. END; {fpart}
  396.  
  397.  
  398. {makes positive flt's negative and vice versa}
  399. PROCEDURE chsF (VAR u:flt);
  400.  
  401. BEGIN
  402. IF ODD(u.exp)
  403.      THEN u.exp:=u.exp-1
  404.      ELSE u.exp:=u.exp+1;
  405. END; {chsF}
  406.  
  407. {returns positive version of number}
  408. FUNCTION absF (u:flt):flt;
  409.  
  410. VAR v:flt;
  411.  
  412. BEGIN
  413. v:=u;
  414. v.exp:=expvalue(u)*2;
  415. absF:=v
  416. END; {absF}
  417.  
  418. {used by addf and subf depending on signs involved}
  419. PROCEDURE sima (u:flt; VAR v:flt);
  420.  
  421. VAR  index        :byte;
  422.      sum,carry    :integer;
  423.      shiftsize    :integer;
  424.      exchange     :flt;
  425.  
  426. BEGIN
  427. IF gtest (u,v)
  428. THEN BEGIN
  429.      exchange:=u;
  430.      u:=v;
  431.      v:=exchange
  432.      END;
  433. shiftsize:=(v.exp-u.exp) DIV 2;
  434. shift (shiftsize,u);
  435. carry:=0;
  436. FOR index := dpmax DOWNTO 1 DO
  437.      BEGIN
  438.      sum:=u.dp[index] + v.dp[index]+carry;
  439.      carry:=sum DIV 100;
  440.      v.dp[index]:=sum MOD 100;
  441.      END; {for}
  442. IF carry>0
  443. THEN BEGIN
  444.      shift(1,v);
  445.      v.dp[1]:=v.dp[1]+(carry*10)
  446.      END
  447. END; {sima}
  448.  
  449. {used by addf and subf according to signs}
  450. PROCEDURE sims (u:flt; VAR v:flt);
  451.  
  452. VAR  index      :byte;
  453.      shiftsize  :integer;
  454.  
  455. PROCEDURE borrow;
  456.  
  457. VAR i        :byte;
  458.     notdone  :boolean;
  459.  
  460. BEGIN
  461. i:=index-1;
  462. notdone:=true;
  463. WHILE notdone DO
  464.      BEGIN
  465.      IF v.dp[i]=0
  466.      THEN BEGIN
  467.           v.dp[i]:=99;
  468.           i:=i-1
  469.           END
  470.      ELSE BEGIN
  471.           v.dp[i]:=v.dp[i]-1;
  472.           notdone:=false
  473.           END
  474.      END
  475. END; {borrow}
  476.  
  477. BEGIN
  478. shiftsize := (v.exp-u.exp) DIV 2;
  479. shift(shiftsize,u);
  480. FOR index:=dpmax DOWNTO 1 DO
  481.      IF v.dp[index]>=u.dp[index]
  482.      THEN v.dp[index]:=v.dp[index]-u.dp[index]
  483.      ELSE BEGIN
  484.           borrow;
  485.           v.dp[index]:=v.dp[index]+100-u.dp[index]
  486.           END;
  487. IF ztest(v)
  488. THEN v.exp:=0
  489. ELSE slar(v);
  490. END; {sims}
  491.  
  492. {used by mulf and divf stands for simple mult. }
  493. PROCEDURE simm (u:flt; VAR v:flt);
  494.  
  495. VAR  w        :flt;
  496.      result   :integer;
  497.      carry    :integer;
  498.      h,i,k    :byte;
  499.  
  500. BEGIN
  501. result:=0;
  502. FOR h:= dpmax DOWNTO 1 DO
  503.      BEGIN
  504.      carry:=0;
  505.      FOR i:=1 TO h DO
  506.           BEGIN
  507.           k:=h+1-i;
  508.           result:=u.dp[i]*v.dp[k]+result;
  509.           carry:= carry+(result DIV 100);
  510.           result:= result MOD 100
  511.           END;
  512.      w.dp[h]:=result;
  513.      result:=carry
  514.      END;
  515. w.exp:=u.exp+v.exp-2;
  516. WHILE result >0 DO
  517.      BEGIN
  518.      carry:=result DIV 10;
  519.      result:=result MOD 10;
  520.      shift(1,w);
  521.      w.dp[1]:=w.dp[1]+(result*10);
  522.      result :=carry
  523.      END;
  524. v:=w
  525. END; {simm}
  526.  
  527. {returns algebraic sum}
  528. FUNCTION addF(u,v:flt):flt;
  529.  
  530. VAR  ucopy,vcopy :flt;
  531.  
  532. BEGIN
  533. ucopy:=u;
  534. vcopy:=v;
  535. IF (ODD(ucopy.exp)=ODD(vcopy.exp))
  536. THEN IF ODD(ucopy.exp)
  537.      THEN BEGIN
  538.           ucopy.exp:=ucopy.exp-1;
  539.           vcopy.exp:=vcopy.exp-1;
  540.           sima(ucopy,vcopy);
  541.           vcopy.exp:=vcopy.exp+1
  542.           END
  543.      ELSE sima(ucopy,vcopy)
  544. ELSE IF ODD(ucopy.exp)
  545.      THEN BEGIN
  546.           ucopy.exp:=ucopy.exp-1;
  547.           IF gtest(vcopy,ucopy)
  548.           THEN sims(ucopy,vcopy)
  549.           ELSE BEGIN
  550.                sims(vcopy,ucopy);
  551.                vcopy:=ucopy;
  552.                vcopy.exp:=vcopy.exp+1
  553.                END
  554.           END
  555.      ELSE BEGIN
  556.           vcopy.exp:=vcopy.exp-1;
  557.           IF gtest(vcopy,ucopy)
  558.           THEN BEGIN
  559.                sims(ucopy,vcopy);
  560.                vcopy.exp:=vcopy.exp +1
  561.                END
  562.           ELSE BEGIN
  563.                sims(vcopy,ucopy);
  564.                vcopy:=ucopy
  565.                END
  566.           END; {else}
  567. addF:=vcopy
  568. END; {addF}
  569.  
  570. {returns (v minus u) }
  571. FUNCTION subF (u,v:flt):flt;
  572.  
  573. VAR w:flt;
  574.  
  575. BEGIN
  576. chsF(u);
  577. w:=addF(u,v);
  578. subF:=w
  579. END; {subF}
  580.  
  581. {tests for equality including sign and exponents}
  582. FUNCTION etest (u,v:flt):boolean;
  583.  
  584. VAR  value: boolean;
  585.      index:byte;
  586.  
  587. BEGIN
  588. value:=true;
  589. IF NOT(u.exp=v.exp)
  590. THEN value:=false;
  591. index:=1;
  592. WHILE value AND (index<=dpmax) DO
  593.      IF u.dp[index]=v.dp[index]
  594.      THEN index:=index+1
  595.      ELSE value:=false;
  596. etest:=value
  597. END; {etest}
  598.  
  599. {returns product}
  600. FUNCTION mulF (u,v:flt):flt;
  601.  
  602. VAR  x,y:flt;
  603.  
  604. BEGIN
  605. x:=u;
  606. y:=v;
  607. IF (ODD(x.exp)=ODD(y.exp))
  608. THEN BEGIN
  609.      x:=absF(x);
  610.      y:=absF(y);
  611.      simm(x,y);
  612.      END
  613. ELSE BEGIN
  614.      x:=absF(x);
  615.      Y:=absF(y);
  616.      simm(x,y);
  617.      y.exp:=y.exp+1
  618.      END;
  619. mulF:=y
  620. END; {mulF}
  621.  
  622. {division by interger n<163 will be used for trig functions}
  623. PROCEDURE diviF (n:integer; VAR u:flt);
  624.  
  625. VAR  rem,result,index                :integer;
  626.  
  627. BEGIN
  628. IF n=0
  629. THEN BEGIN
  630.      errortrap(2,'division by integer zero');
  631.      u.exp:=(u.exp MOD 2)+16000;
  632.      FOR index:=1 TO dpmax
  633.      DO   u.dp[index]:=99;
  634.      END
  635. ELSE BEGIN
  636.      IF n<0
  637.      THEN BEGIN
  638.           chsF(u);
  639.           n:=abs(n)
  640.           END;
  641.      rem:=0;
  642.      FOR index:=1 TO dpmax
  643.      DO   BEGIN
  644.           result:=rem*100+u.dp[index];
  645.           rem:=result MOD n;
  646.           result:=result DIV n;
  647.           IF result >100
  648.           THEN u.dp[index-1]:=(result DIV 100)+u.dp[index-1];
  649.           u.dp[index]:=result MOD 100
  650.           END; {for}
  651.      IF ztest(u)
  652.      THEN u.exp:=0
  653.      ELSE slar(u)
  654.      END; {else}
  655. END; {diviF}
  656.  
  657. {equal except maybe the last digit}
  658. {note 1.00000... isn't semiequal to .999999...}
  659. FUNCTION semiequal (u,v:flt):boolean;
  660.  
  661. VAR  test : boolean;         index : byte;
  662.  
  663. BEGIN
  664. IF u.exp = v.exp
  665. THEN test := true
  666. ELSE test := false;
  667. index := 1;
  668. WHILE test AND (index < dpmax)
  669. DO   BEGIN
  670.      IF u.dp[index] = v.dp[index]
  671.      THEN index := index + 1
  672.      ELSE test := false
  673.      END;
  674. semiequal := test
  675. END; {semiequal}
  676.  
  677. {used by division retruns 1/u }
  678. FUNCTION recipF (u:flt):flt;
  679.  
  680. VAR  one      :flt;
  681.      two      :flt;
  682.      appro    :flt;
  683.      temp     :flt;
  684.      n,e,sign :integer;
  685.      temreal  :real;
  686.  
  687. BEGIN
  688. IF ztest (u)
  689. THEN BEGIN
  690.      appro.exp:=u.exp MOD 2+16000;
  691.      FOR e:=1 TO dpmax DO
  692.           appro.dp[e]:=99;
  693.      ERRORTRAP (2,'Divison by zero')
  694.      END {then}
  695. ELSE BEGIN
  696.      e:=expvalue(u);
  697.      IF ODD(u.exp)
  698.      THEN sign:=1
  699.      ELSE sign:=0;
  700.      setF(1,one);
  701.      IF etest (u,one)
  702.      THEN BEGIN
  703.           appro:=u;
  704.           appro.exp:=(0-e)*2+(sign)
  705.           END
  706.      ELSE BEGIN {inside}
  707.           temreal:=u.dp[1]+(u.dp[2]/100);
  708.           n:=ROUND(100000.0/temreal); {sets good approx}
  709.           setF(n,appro);
  710.           u.exp:=0;
  711.           setF(2,two);
  712.           appro.exp:=-2;
  713.           FOR n:=1 TO ((dpmax +1)DIV 2)
  714.           DO   BEGIN
  715.                temp:=appro;
  716.                simm(u,temp);
  717.                chsF(temp);
  718.                temp:=addF(two,temp);
  719.                simm(temp,appro);
  720.                END; {while}
  721.           appro.exp:=(0-1-e)*2+sign
  722.           END;
  723.      END;
  724. recipF:=appro
  725. END; {recipF}
  726.  
  727.  
  728. {returns (v divided by u) }
  729. FUNCTION divF (u,v:flt):flt;
  730.  
  731. VAR  w:flt;
  732.  
  733. BEGIN
  734. w:=recipF(u);
  735. divF:=mulf(w,v);
  736. END; {divF}
  737.  
  738.  
  739. {square root function for type flt}
  740. FUNCTION sqrtF (u:flt):flt;
  741.  
  742. VAR  root1,delta  :flt;
  743.      temp         :integer;
  744.      rootval      :real;
  745.      roottest:flt;
  746.  
  747. PROCEDURE betterroot;
  748.  
  749. BEGIN
  750. roottest:=root1;
  751. delta :=subF(mulF(root1,root1),u);
  752. diviF(2,delta);
  753. root1:=addF(divF(root1,delta),root1);
  754. END; {betterroot}
  755.  
  756. BEGIN
  757. IF ntest(u)
  758. THEN BEGIN
  759.      errortrap (1,'positive root of neg number');
  760.      u.exp:=u.exp-1
  761.      END;
  762. temp:=u.exp DIV 2;
  763. IF ODD(temp)
  764. THEN temp:=u.dp[1]*100+u.dp[2]
  765. ELSE temp:=u.dp[1]*10+(u.dp[2] DIV 10);
  766. rootval:=sqrt(temp)*100;
  767. temp:=round(rootval);
  768. setF(temp,root1);
  769. root1.exp:=(u.exp DIV 4) * 2;
  770. REPEAT
  771.      betterroot
  772. UNTIL semiequal(root1,roottest);
  773. sqrtF:=root1
  774. END; {sqrtF}
  775.  
  776. {converts any string to a flt number default is}
  777. {0.0e0 if there is no digits present}
  778. PROCEDURE strtoF (num$ : $string255; VAR u :flt);
  779.  
  780. VAR  nextchar                   :char;
  781.      digitflag,expflag          :boolean;
  782.      pastpoint,negexp           :boolean;
  783.      digpos,strpos              :byte;
  784.      value                      :1..9;
  785.      afterE                     :integer; {entered part of exponent}
  786.      i                          :integer;
  787.  
  788. PROCEDURE processchar;
  789.  
  790. BEGIN
  791. nextchar:=num$[strpos];
  792. CASE nextchar OF
  793.      'E','e'  :IF digitflag
  794.                THEN expflag:=true;
  795.      '-'  :IF expflag
  796.            THEN negexp:=true
  797.            ELSE u.exp :=(u.exp DIV 2)*2 +1;
  798.      '0'  :IF expflag
  799.            THEN BEGIN
  800.                 if afterE<1630
  801.                 then afterE:=afterE*10
  802.                 END
  803.            ELSE if pastpoint
  804.                 then if digitflag
  805.                      then digpos:=digpos+1
  806.                      else u.exp:=u.exp-2 {allows entry of .00 ... 001}
  807.                 else if digitflag
  808.                      then begin
  809.                           digpos:=digpos+1;
  810.                           u.exp:=u.exp+2
  811.                           end;
  812.      '.'  :BEGIN
  813.            pastpoint := true;
  814.            END;
  815.      '1','2','3','4','5','6','7','8','9'
  816.           :BEGIN
  817.            digitflag := true;
  818.            IF expflag
  819.            THEN BEGIN
  820.                 value:=ord(nextchar)-ord('0');
  821.                 if afterE<1630
  822.                 then afterE:=afterE*10+value
  823.                 END
  824.            ELSE BEGIN
  825.                 IF digpos < digmax
  826.                 THEN BEGIN
  827.                      value:=ord(nextchar)-ord('0');
  828.                      i:=(digpos +1) DIV 2;
  829.                      IF ODD(digpos)
  830.                      THEN u.dp[i]:=value*10
  831.                      ELSE u.dp[i]:=u.dp[i]+value;
  832.                      digpos:=digpos+1;
  833.                      end; {then}
  834.                 IF NOT(pastpoint)
  835.                 THEN u.exp:=u.exp+2;
  836.                 END
  837.            END; {digits}
  838.      END; {case}
  839. END; {processchar}
  840.  
  841. BEGIN
  842. setF(0,u);
  843. u.exp:=-2;
  844. afterE:=0;
  845. digitflag :=false;
  846. expflag:=false;
  847. pastpoint:=false;
  848. negexp:=false;
  849. digpos:=1;
  850. FOR strpos := 1 TO length(num$)
  851. DO   processchar;
  852. IF negexp
  853. then u.exp:=u.exp-(2*afterE)
  854. else u.exp:=u.exp+(2*afterE)
  855. END; {strtoF}
  856.  
  857. {$iftostr.txt }
  858.  
  859. {the program is just a short demo}
  860.  
  861. BEGIN
  862. error$:='MATHPACK';
  863. writeln (error$);
  864. setlength(error$,0);
  865. append(error$,'fltmath');
  866. m:=1739;
  867. n:=-831;
  868. setF (8246,u);
  869. setF (m,w);
  870. setF (n,v);
  871. dispF (u);
  872. dispF (w);
  873. dispF (v);
  874. shift(-1,v);
  875. dispF (v);
  876. w:=addF(u,w);
  877. dispF(w);
  878. w:=subF(u,w);
  879. dispF(w);
  880. w:=mulF(u,w);
  881. dispF(w);
  882. diviF(29,v);
  883. dispF(v);
  884. v:=recipF(w);
  885. dispF(v);
  886. writeln;
  887. v:=divF(u,w);
  888. dispF(v);
  889. writeln;
  890. dispF(w);
  891. v:=sqrtF(w);
  892. dispF(v);
  893.      i$:='9.75312468E-14';
  894.      strtoF(i$,u);
  895.      strtoF('-3.161',v);
  896.      FOR m:=1 to 60
  897.      DO   BEGIN
  898.           u:=mulF(v,u);
  899.           dispF(u); {for comparison purposes}
  900.           Ftostr(u,12,'6');
  901.           writeln;
  902.           writeln;
  903.           END;
  904. repeat
  905.      writeln;
  906. writeln('Enter stop to stop loop');
  907.      write('Enter number to be converted : ');
  908.      readln(i$);
  909.      strtoF(i$,w);
  910.      Ftostr(w,10,'4')
  911. until i$='stop';
  912. END. {mathpack.pas}
  913.