home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume3 / ieee / part6 < prev    next >
Encoding:
Internet Message Format  |  1986-11-30  |  26.2 KB

  1. From: genrad!decvax!decwrl!sun!dgh!dgh (David Hough)
  2. Subject: IEEE Calculator (part 6 of 6)
  3. Newsgroups: mod.sources
  4. Approved: jpn@panda.UUCP
  5.  
  6. Mod.sources:  Volume 3, Issue 8
  7. Submitted by: decvax!decwrl!sun!dgh!dgh (David Hough)
  8.  
  9. #! /bin/sh
  10. : make a directory, cd to it, and run this through sh
  11. echo If this kit is complete, "End of Kit" will echo at the end
  12. echo Extracting forward.i
  13. cat >forward.i <<'End-Of-File'
  14. (* File forward.i, Version 8 October 1984.  *)
  15.  
  16.                         (* FORWARDs for CALC   *)
  17.                         
  18. procedure adder ( x, y : boolean ; var z : boolean ; var carry : boolean ) ;
  19. forward ;
  20. procedure suber ( x, y : boolean ; var z : boolean ; var carry : boolean ) ;
  21. forward ;
  22.  
  23. procedure bindec ( x : internal ; var s : strng ) ;
  24. forward ;
  25.  
  26. procedure binhex ( x : internal ; var s : strng ) ;
  27. forward ;
  28.  
  29. procedure compare ( x, y : internal ; var cc : conditioncode ) ;
  30. forward ;
  31.  
  32. procedure add ( x, y : internal ; var z : internal ) ; forward ;
  33.  
  34. procedure decbin ( s : strng ; var x : internal ; var error : boolean ) ;
  35. forward ;
  36.  
  37. procedure hexbin ( s : strng ; var x : internal ; var error : boolean ) ;
  38. forward ;
  39.  
  40. procedure putdec ( s : strng ; p1, p2 : integer ; var x : internal ;
  41.                         var error : boolean ) ;
  42. forward ;
  43.  
  44. procedure subdec ( x : internal ; p1, p2 : integer ; var s : strng ) ;
  45. forward ;
  46.  
  47. function nibblehex ( n : nibarray ) : char ;
  48. forward ;
  49.  
  50. procedure setex ( e : xcpn ) ; forward ;
  51.  
  52. function zerofield ( x : internal ; p1, p2 : integer ) : boolean ;
  53. forward ;
  54.  
  55. function firstbit ( x : internal ; p1, p2 : integer ) : integer ;
  56. forward ;
  57.  
  58. function lastbit ( x : internal ; p1, p2 : integer ) : integer ;
  59. forward ;
  60.  
  61. function kind ( x : internal ) : integer ;
  62. forward ;
  63.  
  64. procedure makezero ( var x : internal ) ;
  65. forward ;
  66.  
  67. procedure makeinf ( var x : internal ) ;
  68. forward ;
  69.  
  70. procedure makenan ( n : integer ; var x : internal ) ;
  71. forward ;
  72.  
  73. function unzero ( x : internal ) : boolean ;
  74. forward ;
  75.  
  76. procedure donormalize ( var x : internal ) ;
  77. forward ;
  78.  
  79. procedure right ( var x: internal ; n : integer ) ;
  80. forward ;
  81.  
  82. procedure left ( var x : internal ; n : integer ) ;
  83. forward ;
  84.  
  85. procedure roundkcs ( var x: internal ; r : roundtype ; p : extprec ) ;
  86. forward ;
  87.  
  88. procedure picknan ( x, y : internal ; var z : internal ) ;
  89. forward ;
  90.  
  91. procedure roundint ( var x : internal ; r : roundtype ; p : extprec ) ;
  92. forward ;
  93.  
  94. procedure unpackinteger ( y : cint64 ; var x : internal ; itype : inttype ) ;
  95. forward ;
  96.  
  97. procedure store ( var x : internal ) ;
  98. forward ;
  99.  
  100. procedure display ( x : internal ) ; forward ;
  101.  
  102. procedure popstack ( var x : internal ) ; forward ;
  103.  
  104. procedure pushstack ( x : internal ) ; forward ;
  105.  
  106. procedure dotest ( s : strng ; var found : boolean ; x, y : internal ) ;
  107. forward ;
  108.  
  109.  
  110. End-Of-File
  111. echo Extracting function.i
  112. cat >function.i <<'End-Of-File'
  113. (* File Calc:Function, Version 24 May 1984.    *)
  114.  
  115. procedure compare (* x, y : internal ; var cc : conditioncode *) ;
  116.  
  117.         (* computes X comp Y and returns result cc *)
  118.  
  119.  
  120. procedure docomp ;
  121.         (* does bitwise X comp Y and returns result in cc *)
  122.         (* Works like -INF < -NORM < -0 < +0 < +NORM < +INF
  123.         so don't use to compare two zeros or to compare with INF
  124.         in proj mode *)
  125.         
  126. var i : integer ;
  127.  
  128. begin
  129. cc := equal ;
  130. if x.sign <> y.sign then
  131. if x.sign then cc := lesser else cc := greater 
  132. else begin (* same signs *)
  133. if x.exponent < y.exponent then cc := lesser 
  134. else if x.exponent > y.exponent then cc := greater
  135. else begin (* same sign and same exponent *)
  136. i := 0 ;
  137. while ( i < stickybit) and (x.significand[i]=y.significand[i]) do i := i + 1 ;
  138. if i <> stickybit then 
  139. if x.significand[i] then cc := greater else cc := lesser ;
  140. end ;
  141. if x.sign then case cc of (* if negative numbers, reverse conclusion *)
  142. lesser : cc := greater ;
  143. greater : cc := lesser ;
  144. end ;
  145. end ;
  146. end ;
  147.  
  148. begin (* compare *)
  149. roundkcs ( x, fpstatus.mode.round, xprec ) ; (* Preround; ignore inxact. *)
  150. donormalize(x) ;
  151. roundkcs (y, fpstatus.mode.round, xprec ) ; (* Preround; ignore inxact. *)
  152. donormalize(y) ;
  153. fpstatus.curexcep := fpstatus.curexcep - [inxact] ; (* Ignore.  *)
  154. case abs(kind(x)) of
  155.  
  156. zerokind: case abs(kind(y)) of
  157. zerokind : cc := equal ;
  158. normkind : docomp ;
  159. infkind : if fpstatus.mode.clos = proj then cc := notord
  160. else docomp ;
  161. nankind : cc := notord ;
  162. end ;
  163.  
  164. normkind : case abs(kind(y)) of
  165. zerokind , normkind : docomp ;
  166. infkind : if fpstatus.mode.clos = proj then cc := notord
  167. else docomp ;
  168. nankind : cc := notord ;
  169. end ;
  170.  
  171. infkind : case abs(kind(y)) of
  172. zerokind, normkind : if fpstatus.mode.clos = proj then
  173.         cc := notord else docomp ;
  174. infkind : if fpstatus.mode.clos = proj then cc := equal
  175. else docomp ;
  176. nankind : cc := notord ;
  177. end ;
  178.  
  179. nankind : cc := notord ;
  180. end ;
  181.  
  182. end ;
  183.  
  184. procedure add (* x, y : internal ; var z : internal  *) ;
  185.  
  186.         (* Does z := x + y  *)
  187.         
  188. procedure doadd ;
  189.  
  190.         (* Does true add z := x + y
  191.         Neither x nor y should be INF or NAN
  192.         x and y should not both be true zero.  *)
  193.         
  194. var
  195. carry : boolean ;
  196. i : integer ;
  197. shiftcount : integer ;
  198.  
  199. begin
  200. roundkcs( x, fpstatus.mode.round, xprec) ; (* Pre-round.  *)
  201. roundkcs( y, fpstatus.mode.round, xprec) ;
  202.  
  203. z.sign := x.sign ;
  204.  
  205. if x.exponent >= y.exponent then begin (* Align smaller operand.  *)
  206. z.exponent := x.exponent ;
  207. shiftcount := x.exponent - y.exponent ;
  208. if shiftcount < 0 then shiftcount := maxexp ;
  209. right( y, shiftcount ) ;
  210. end
  211. else begin
  212. z.exponent := y.exponent ;
  213. shiftcount := y.exponent - x.exponent ;
  214. if shiftcount < 0 then shiftcount := maxexp ;
  215. right( x, shiftcount ) ;
  216. end ;
  217.  
  218. carry := false ;
  219. for i := stickybit downto 0 do
  220. adder( x.significand[i], y.significand[i], z.significand[i], carry ) ;
  221.  
  222. if carry then begin (* Renormalize for carry out.  *)
  223. right( z, 1 ) ;
  224. z.significand[0] := true ;
  225. z.exponent := z.exponent + 1 ;
  226. end ;
  227.  
  228. end ;
  229.  
  230. procedure dosub ; 
  231.  
  232.         (* Does true subtract z := x - y,
  233.         neither of which should be INF or NAN,
  234.         only one of which should be true zero.  *)
  235.         
  236. var
  237. carry : boolean ;
  238. shiftcount, i : integer ;
  239. postnorm : boolean ;
  240. rnd : roundtype ;
  241. redo : boolean ;
  242. xur, yur : internal ; (* Save x and y unrounded operands.  *)
  243.  
  244. begin
  245.         (* Proper preround is ambiguous in the case when the indicated
  246.         rounding mode is RZ and a true subtract is required.
  247.         x and y should be rounded RM if the result is positive,
  248.         RP if the result is negative.
  249.         Occasionally the result comes out reversed and the operands
  250.         have to be re-pre-rounded.
  251.         All this makes a good argument for not having pre-rounding or at
  252.         least fudging this one annoying case.  *)
  253.         
  254. y.sign := not y.sign ; (* Reverse sign of y so x and y have same signs.  *)
  255. xur := x ; yur := y ; (* Save unrounded operands.  *)
  256. redo := false ; (* Set true if we go through loop twice.  *)
  257.  
  258. repeat
  259. x := xur ; y := yur ; (* Restore unrounded state.  *)
  260. rnd := fpstatus.mode.round ; (* This is almost always appropriate.  *)
  261.  
  262. if x.exponent >= y.exponent then begin
  263. z.sign := x.sign ;
  264. z.exponent := x.exponent ;
  265. if rnd = rzero then begin
  266. if x.sign <> redo then rnd := rpos else rnd := rneg end  ;
  267. roundkcs ( x, rnd, xprec ) ;
  268. roundkcs ( y, rnd, xprec ) ;
  269. shiftcount := x.exponent - y.exponent ;
  270. if shiftcount < 0 then shiftcount := maxexp ;
  271. right ( y, shiftcount ) ;
  272. end
  273. else begin
  274. z.sign := not y.sign ;
  275. z.exponent := y.exponent ;
  276. if rnd = rzero then begin  (*  Bad case.  *)
  277. if y.sign <> redo then rnd := rpos else rnd := rneg end  ;
  278. roundkcs( x, rnd, xprec ) ;
  279. roundkcs( y, rnd, xprec ) ;
  280. shiftcount := y.exponent - x.exponent ;
  281. if shiftcount < 0 then shiftcount := maxexp ;
  282. right ( x, shiftcount ) ;
  283. end ;
  284.  
  285. postnorm := x.significand[0] or y.significand[0] ;
  286.         (* Post normalization occurs if larger operand is normalized.  *)
  287.  
  288. carry := false ;
  289. if z.sign = x.sign then for i := stickybit downto 0 do
  290. suber( x.significand[i], y.significand[i], z.significand[i], carry ) 
  291. else for i := stickybit downto 0 do 
  292. suber( y.significand[i], x.significand[i], z.significand[i], carry ) ;
  293.  
  294. if carry then begin (* Sign reversal.  *)
  295. z.sign := not z.sign ;
  296. carry := true ; (* For end-around carry.  *)
  297. for i := stickybit downto 0 do
  298. adder( not z.significand[i], false, z.significand[i], carry ) ; 
  299. (* Complement.  *)
  300. redo := fpstatus.mode.round = rzero ; (* Pre-round was inappropriate.  *)
  301. if redo then writeln(' RE-PRE-ROUND required for SUBTRACT.  ') ;
  302. end ;
  303.  
  304. until not redo ;
  305.  
  306. if postnorm then donormalize(z) ; (* Do renormalization.  *)
  307.  
  308. store(z) ; (* Force round to storage mode to determine if the result will
  309.                 be zero; if so, special sign rules apply.  *)
  310. if zerofield( z, 0, leastsigbit )  then (* Correct sign for zero result.  *)
  311. z.sign := fpstatus.mode.round = rneg ;  (* Which is +0 except in RM mode.  *)
  312.  
  313. end ;
  314.  
  315. begin (* add *)
  316. if (abs(kind(x))=nankind) or (abs(kind(y))=nankind) then
  317. picknan( x, y, z) else
  318.  
  319. case abs(kind(x)) of
  320.  
  321. zerokind : case abs(kind(y)) of
  322.  
  323. zerokind : begin (* +-0 + +-0 *)
  324. z := x ;
  325. if x.sign <> y.sign then z.sign := fpstatus.mode.round = rneg ;
  326.         (* +0 + -0 usually has sign +0 except in RM mode.  *)
  327. end ;
  328. unnormkind, normkind : if x.sign = y.sign then doadd else dosub ;
  329. infkind : z := y ;
  330. end ;
  331.  
  332. unnormkind, normkind : if abs(kind(y)) = infkind then z := y else
  333. if x.sign = y.sign then doadd else dosub ;
  334.  
  335. infkind : if abs(kind(y)) <> infkind then z := x else (* INF +- INF *)
  336. if (fpstatus.mode.clos = proj) or (x.sign <> y.sign) 
  337. then makenan ( nanadd, z )
  338. else z := x ;
  339.  
  340. end ;
  341.  
  342. end ;
  343.  
  344. procedure multiply (x , y : internal ; var z : internal  ) ;
  345.         
  346.         (* routine to multiply two internal numbers and return z := x*y
  347.         with curexcep  containing flags set. *)
  348.         
  349. var dorout : boolean ;
  350.  
  351. procedure domult ; 
  352.  
  353.         (* does the multiply of z := abs(x) * abs(y) *)
  354.         
  355. var
  356. i, j, j0, n0, n1  : integer ;
  357. carry : boolean ;
  358. r : roundtype ;
  359. xlast, ylast : integer ;
  360. xfirst, yfirst : integer ;
  361.  
  362.                 (* The following subprocedures do various cases of
  363.                 multiply substeps.  Based on Booth algorithm ideas.  *)
  364.  
  365. procedure don0 ;
  366.  
  367.         (* Multiplies z by n0 zeros, i. e. right shifts n0 times,
  368.         and resets n0.  *)
  369.         
  370. var i : integer ;
  371.  
  372. begin
  373. z.significand[stickybit] := not zerofield ( z, stickybit-n0, stickybit ) ;
  374.                 (* Shift bits into stickybit.  *)
  375. for i := (stickybit-1) downto n0 do
  376. z.significand[i] := z.significand[i-n0] ; (* Really shift bits.  *)
  377. for i := (n0-1) downto 0 do
  378. z.significand[i] := false ; (* Shift in zeros at left.  *)
  379. n0 := 0 ;
  380. end ;
  381.  
  382. procedure do11 ;
  383.  
  384.         (* Does add y and shift to z.  *)
  385.         
  386. var
  387. j : integer ;
  388. carry : boolean ;
  389.  
  390. begin
  391. if z.significand[stickybit-1] then z.significand[stickybit] := true ;
  392. for j := (stickybit-1) downto (ylast+2) do  (* These bits only shift.  *)
  393. z.significand[j] := z.significand[j-1] ;
  394. carry := false ;
  395. for j := (ylast+1) downto (yfirst+1) do
  396. adder( z.significand[j-1], y.significand[j-1], z.significand[j], carry ) ;
  397. z.significand[yfirst] := carry ;
  398. end ;
  399.  
  400. procedure do21 ;
  401.  
  402.         (* Does twice:  add y and shift z.  *)
  403.         
  404. begin
  405. do11 ; do11 ;
  406. end ;
  407.  
  408. procedure don1 ;
  409.  
  410.         (* Does n1 times: add y and shift z, by
  411.         1) subtract y
  412.         2) shift z n1 times
  413.         3) add 2*y
  414.                                         *)
  415.                                         
  416. var
  417. j, j0 : integer ;
  418. carry : boolean ;
  419.  
  420. begin
  421. if n1=1 then do11 else if n1=2 then do21 else begin
  422.                         (* Do subtract.  *)
  423. carry := false ;
  424. for j := (ylast) downto (yfirst) do
  425. suber( z.significand[j], y.significand[j], z.significand[j], carry ) ;
  426. for j := (yfirst-1) downto 0 do (* Ripple carry.  *)
  427. z.significand[j] := true ;
  428.                         (* Do shift.  *)
  429. z.significand[stickybit] := not zerofield( z, stickybit-n1, stickybit ) ;
  430. for j := (stickybit-1) downto n1 do
  431. z.significand[j] := z.significand[j-n1] ;
  432. for j := (n1-1) downto 0 do 
  433. z.significand[j] := true  ;
  434.                         (* Do add 2*y.  *)
  435. carry := false ;
  436. for j := ylast downto yfirst do
  437. adder( z.significand[j], y.significand[j], z.significand[j], carry ) ;
  438. end ;
  439. for j := (yfirst-1) downto 0 do
  440. z.significand[j] := false ;
  441. n1 := 0 ;
  442. end ;
  443.  
  444. begin
  445.         (* Preround. *)
  446. dorout := false ;
  447. case fpstatus.mode.round of
  448. rnear, rzero : r := fpstatus.mode.round ;
  449. rneg : if x.sign = y.sign then r := rzero else dorout := true ;
  450. rpos : if x.sign = y.sign then dorout := true   else r := rzero ;
  451. end ;
  452. if dorout then
  453.         begin (* round out *)
  454.         if x.sign then roundkcs( x, rneg, xprec ) else roundkcs( x, rpos, xprec ) ;
  455.         if y.sign then roundkcs( y, rneg, xprec ) else roundkcs( y, rpos, xprec ) ;
  456.         end   (* round out *) 
  457.         else
  458.         begin 
  459.         roundkcs( x, r, xprec ) ;
  460.         roundkcs( y, r, xprec ) ;
  461.         end ;
  462.  
  463. xfirst := firstbit( x, 0, leastsigbit) ;
  464. yfirst := firstbit( y, 0, leastsigbit ) ;
  465. if xfirst <= leastsigbit then
  466. xlast := lastbit( x, xfirst, leastsigbit) else xlast := -1 ;
  467. if yfirst <= leastsigbit then
  468. ylast := lastbit( y, yfirst, leastsigbit) else ylast := -1 ;
  469.  
  470. if (xfirst > xlast) or (yfirst > ylast)  then begin 
  471. (* z is unnormalized zero.  *)
  472. makezero(z) ;
  473. z.exponent := x.exponent + y.exponent - 1 ;
  474. end
  475.  
  476. else begin (* Both operands are non-zero.  *)
  477.  
  478. z.exponent := x.exponent + y.exponent ;
  479. for i := 0 to stickybit do z.significand[i] := false ;
  480. n1 := 0 ; n0 := 0 ;
  481. for i := xlast downto xfirst do  (* for each bit of x *)
  482. if x.significand[i] then 
  483. begin
  484.         (* Encounter One.  *)
  485. if n0 > 0 then begin
  486. don0 ;
  487. n1 := 1 ;
  488. end 
  489. else n1 := n1 + 1
  490. end
  491.  
  492. else begin
  493.         (* Encounter Zero.  *)
  494. if n1 > 0 then begin
  495. don1 ;
  496. n0 := 1 ;
  497. end
  498. else n0 := n0 + 1
  499. end ;
  500.  
  501. if n1 > 0 then don1 ; (* Tidy up at end.  *)
  502. n0 := n0 + xfirst ; 
  503. (* Additional right shifts necessary if x not normalized.  *)
  504. if n0 > 0 then don0 ;
  505.  
  506. if not z.significand[0] then begin (* Do one donormalize cycle *)
  507. z.exponent := z.exponent - 1 ;
  508. left(z, 1 ) ;
  509. end ;
  510. end ;
  511. if (x.exponent < 0) and (y.exponent < 0) and (z.exponent > 0) then begin
  512.         (* Gross underfl has caused integer overfl leading to large
  513.         positive exponent.  *)
  514. right(z,stickybit) ;
  515. z.exponent := minexp ;
  516. setex(underfl) ;
  517. end ;
  518. end ;
  519.  
  520. begin
  521. if (abs(kind(x))=nankind) or (abs(kind(y))=nankind) then picknan(x,y,z) else
  522. case abs(kind(x)) of
  523. zerokind : case abs(kind(y)) of
  524. zerokind, unnormkind,  normkind : z := x ;
  525. infkind : makenan(nanmul, z) ;
  526. end ;
  527.  
  528. unnormkind : case abs(kind(y)) of
  529. zerokind: z := y ;
  530. unnormkind, normkind : domult ;
  531. infkind : if unzero(y) then makenan( nanmul, z) else z := y ;
  532. end ;
  533.  
  534. normkind : case abs(kind(y)) of
  535. zerokind : z := y ;
  536. unnormkind, normkind : domult ;
  537. infkind : z := y ;
  538. end ;
  539.  
  540. infkind : case abs(kind(y)) of
  541. zerokind : makenan( nanmul, z ) ;
  542. unnormkind : if unzero(y) then makenan(nanmul, z) else z := x ;
  543. normkind , infkind : z := x ;
  544. end ;
  545. end ;
  546.  
  547. z.sign := (x.sign <> y.sign) ; (* exclusive OR signs *)
  548.  
  549. end ;
  550.  
  551. procedure divide ( x, y : internal ; var z : internal  ) ;
  552.  
  553.         (* Does extended internal divide z := x/y *)
  554.         
  555.  
  556. procedure divbyzero ; (* for invalid divide exception *)
  557. begin
  558. makezero(z) ;
  559. z.exponent := maxexp ; (* Make Infinity result *)
  560. setex( div0 ) ;
  561. end ;
  562.  
  563. procedure dodiv ; 
  564.  
  565.         (* carries out divide of x by normalized y *)
  566.         (* x should be nonzero and finite *)
  567.         (* signs are ignored *)
  568.         
  569. var
  570. i,j : integer ;
  571. carry, sbit, tbit : boolean ;
  572. r : internal ;
  573. rx, ry : roundtype ;
  574. rlast, ylast  : integer ;
  575. xrout, yrout : boolean ;
  576.  
  577. begin
  578.         (* Preround. *)
  579. xrout := false ; yrout := false ;
  580. case fpstatus.mode.round of
  581. rnear : begin
  582. rx := rnear ;
  583. ry := rnear ;
  584. end ;
  585. rzero : begin
  586. rx := rzero ;
  587. yrout := true ;
  588. end ;
  589. rneg : if x.sign = y.sign then begin
  590. rx := rzero ;
  591. yrout := true ;
  592. end
  593. else begin
  594. xrout := true ;
  595. ry := rzero ;
  596. end ;
  597. rpos: if x.sign = y.sign then begin
  598. xrout := true ;
  599. ry := rzero ;
  600. end
  601. else begin
  602. rx := rzero ;
  603. yrout := true ;
  604. end ;
  605. end ;
  606. if xrout then 
  607.         begin
  608.         if x.sign then roundkcs( x, rneg, xprec ) else roundkcs ( x, rpos, xprec )
  609.         end
  610.         else roundkcs( x, rx, xprec) ;
  611. if yrout then begin
  612.         if y.sign then roundkcs( y, rneg, xprec ) else roundkcs ( y, rpos, xprec )
  613.         end
  614. else roundkcs( y, ry, xprec) ;
  615.  
  616. ylast := lastbit ( y, 0, leastsigbit ) ;
  617. rlast := lastbit ( x, 0, leastsigbit ) + 1 ;
  618. if rlast < (ylast+1) then rlast := ylast + 1  ;
  619.  
  620. for i := 0 to (rlast-1) do 
  621. r.significand[i+1] := x.significand[i] ; (* remainder R := X/2 *)
  622. r.significand[0] := false ;
  623. z.exponent := x.exponent - y.exponent + 1 ;
  624. sbit := false ; (* Sbit contains the sign of the remainder between steps *)
  625.  
  626. for i := 0 to (stickybit-1) do begin (* for each bit of result *)
  627. tbit := sbit ; (* T bit holds test to decide + or -.  *)
  628. sbit := r.significand[ylast+1] ;
  629. for j := (ylast+1) to (rlast-1) do
  630. r.significand[j] := r.significand[j+1] ;
  631. carry := false ;
  632.  
  633. if tbit then begin (* If R < 0 then R := 2 * (R+Y) *)
  634. for j := ylast downto 0 do begin
  635. adder(sbit, y.significand[j], tbit, carry) ;
  636. sbit := r.significand[j] ;
  637. r.significand[j] := tbit ;
  638. end ;
  639. adder( sbit, false, sbit, carry) ; (* Sbit now has the sign of R *)
  640. end
  641. else begin (* If R >= 0 then R := 2 * (R-Y) *)
  642. for j := ylast  downto 0 do begin
  643. suber(sbit, y.significand[j], tbit, carry) ;
  644. sbit := r.significand[j] ;
  645. r.significand[j] := tbit ;
  646. end ;
  647. suber(sbit, false, sbit, carry) ; (* Sbit now has the sign of R *)
  648. end ;
  649. r.significand[rlast] := false ; (* result of left shift *)
  650. z.significand[i] := not sbit ; (* Result bit for this step *)
  651. end ;
  652.  
  653. (* Next check for sticky bit.  Result Z is exact iff
  654.         R = 0 or R <= -2Y  *)
  655.         
  656. z.significand[stickybit] := true ; (* Result is almost always inexact *)
  657. if sbit then begin (* R < 0 so compute R + 2Y *)
  658. carry := false ;
  659. for j := rlast downto 0 do
  660. adder(r.significand[j], y.significand[j], r.significand[j], carry) ;
  661. z.significand[stickybit] :=  carry ; (* If no carry then R+2Y < 0 *)
  662. end ;
  663. if z.significand[stickybit] then begin (* check if R >=0 or R+2Y >= 0 *)
  664. (* R >= 0 ; Is R = 0 ? *)
  665. z.significand[stickybit] := not zerofield ( r, 0, rlast )  ;
  666. end ;
  667.  
  668.  
  669. if not z.significand[0] then begin (* normalize once *)
  670. z.exponent := z.exponent - 1 ;
  671. for i := 1 to stickybit do z.significand[i-1] := z.significand[i] ;
  672. end ;
  673.  
  674. if (x.exponent < 0) and (y.exponent < 0) and (z.exponent > 0) then begin
  675.         (* Gross underfl has caused integer overfl leading to large
  676.         positive exponent.  *)
  677. right(z,stickybit) ;
  678. z.exponent := minexp ;
  679. setex(underfl) ;
  680. end ;
  681. end ;
  682.  
  683.  
  684.  
  685. begin (* divide *)
  686. case abs(kind(x)) of
  687.  
  688. zerokind: case abs(kind(y)) of
  689. zerokind: makenan( nandiv, z) ;
  690. unnormkind: if unzero(y) then makenan(nandiv, z) else z := x ;
  691. normkind, infkind : z := x ;
  692. nankind : z := y ;
  693. end ;
  694.  
  695. unnormkind : case abs(kind(y)) of
  696. zerokind : if unzero(x) then makenan(nandiv, z) else divbyzero ;
  697. unnormkind : makenan( nandiv, z) ;
  698. normkind :  dodiv ;
  699. infkind : makezero(z) ;
  700. nankind : z := y ;
  701. end ;
  702.  
  703. normkind : case abs(kind(y)) of
  704. zerokind : divbyzero ;
  705. unnormkind : makenan(nandiv,z) ;
  706. normkind : dodiv ;
  707. infkind : makezero(z) ;
  708. nankind : z := y ;
  709. end ;
  710.  
  711. infkind : case abs(kind(y)) of
  712. zerokind, unnormkind, normkind : z := x ;
  713. infkind : makenan(nandiv,z) ;
  714. nankind : z := y ;
  715. end ;
  716.  
  717. nankind : picknan( x, y, z) ;
  718. end ;
  719.  
  720. z.sign := x.sign <> y.sign ; (* Do Exclusive Or *)
  721. end ;
  722.  
  723.  
  724. End-Of-File
  725. echo Extracting global.i
  726. cat >global.i <<'End-Of-File'
  727. (* File Calc:Global, Version 24 May 1984.     *)
  728.  
  729. (* global constant, type, and variable declarations for  calc *)
  730.  
  731. const
  732. leastsigbit = 63 ; 
  733. (* Position of least significant bit in external extended.  *)
  734.  
  735. maxexp  = 32767 ; (* 2**15-1, maximum internal exponent *)
  736. (* used for INF and NAN *)
  737. minexp  = -maxexp ;
  738. (* -2**15+1, minimum internal exponent, used for zero *)
  739.  
  740. biasex = 16383 ; (* Extended exponent bias.  *)
  741. maxex = 16384 ; (* Extended maximum unbiased exponent.  *)
  742. minex = -16383 ; (* Extended minimum unbiased exponent.  *)
  743.  
  744. biased = 1022 ; (* Double exponent bias.  *)
  745. maxed = 1025 ; (* Double maximum unbiased exponent.  *)
  746. mined = -1022 ; (* Double minimum unbiased exponent.  *)
  747.  
  748. biases = 126 ; (* Single exponent bias.  *)
  749. maxes = 129 ; (* Single maximum unbiased exponent.  *)
  750. mines = -126 ; (* Single minimum unbiased exponent.  *)
  751.  
  752. zerokind = 0 ; (* KIND of zero *)
  753. unnormkind = 1 ; (* KIND of denormalized or unnormalized *)
  754. normkind = 2 ; (* KIND of normalized number *)
  755. infkind = 3 ; (* KIND of infinity *)
  756. nankind = 4 ; (* KIND of NAN *)
  757. negunnorm = -1 ; 
  758. negnorm = -2 ;
  759. neginf = -3 ;
  760. negnan = -4 ;
  761.  
  762. ordbell = 7 ; (* ASCII code for Bell.  *)
  763.  
  764. nanfields = 4 ; (* Number of fields in NAN significand.  *)
  765. {
  766. notord = unord ;
  767. }
  768. nansqrt = 1 ;
  769. nanadd = 2 ;
  770. nanint = 3 ;
  771. nandiv = 4 ;
  772. nantrap = 5 ;
  773. nanunord = 6 ;
  774. nanproj = 7 ;
  775. nanmul = 8 ;
  776. nanrem = 9 ;
  777. nanresult = 12 ;
  778. nanascbin = 17 ;
  779. nanascnan = 18 ;
  780. naninteger = 20 ;
  781. nanzero = 21 ;
  782.  
  783. type
  784.  
  785. strng = fpstring ; (* Standard string type.  *)
  786.  
  787. inttype = i16 .. i64 ; (* Types of integer operands.  *)
  788.  
  789. sxinternal = record (* Special signless single extended internal format.  *)
  790.         exponent : integer ;
  791.         significand : array[0..1] of integer ;
  792.         end ;
  793.  
  794. pstack = ^ stacktype ;
  795.  
  796. stacktype = record (* item on stack *)
  797. x : internal ;
  798. next : pstack ;
  799. end ;
  800.  
  801. nibarray = array[0..3] of boolean ;
  802.  
  803. var
  804. fpstatus : fpstype ; (* current status *)
  805. storagemode : arithtype ; (* current storage mode *)
  806.         (* Each operand is rounded to this mode after operation.  *)
  807. testflag : boolean ; (* True if DOTEST is to be called.  *)
  808. stack : pstack  ;
  809. digitset, hexset : set of char ;
  810.  
  811. tensmall : array [ 0 .. 31 ] of internal ; (* Table of small powers of ten *)
  812. tenbig : array [ 0 .. 31 ] of internal ; (* Table of big powers of ten *)
  813. pi, e : internal ; (* Familiar constants.  *)
  814.  
  815. leftnan, rightnan : array [ 1 .. nanfields ] of 0 .. stickybit ; 
  816.         (* Indexes of bitfield boundaries for NAN significands.  *)
  817.  
  818. xcpnname : array [ exception                               ] of
  819.         packed array [1..2] of char ;
  820.         (* Two character codes for exceptions.  *)
  821.  
  822.  
  823. End-Of-File
  824. echo Extracting addsubpas.i
  825. cat >addsubpas.i <<'End-Of-File'
  826. procedure adder (* x, y : boolean ; var z : boolean ; var carry : boolean *);
  827.  
  828.         (* computes boolean z := x + y with carry in and out *)
  829.         
  830.         
  831. begin
  832. z := carry ;
  833. carry := z and x ;
  834. z := ( z <> x ) ;
  835. if carry then z := y else begin
  836. carry := (z and y) ;
  837. z := (z <> y) ;
  838. end ;
  839. end ;
  840.  
  841. procedure suber (* x, y : boolean ; var z : boolean ; var carry : boolean *) ;
  842.  
  843.  
  844.         (* computes boolean z := x - y with carry in and out *)
  845.  
  846. begin
  847. z := y <> carry ;
  848. carry := carry and y ;
  849. if carry then z := x else begin
  850. carry := (z and (not x)) ;
  851. z := (z <> x) ;
  852. end ;
  853. end ;
  854. End-Of-File
  855. echo Extracting divrem.i
  856. cat >divrem.i <<'End-Of-File'
  857. (* File Calc:Divrem, Version 19 February 1982.  *)
  858.  
  859. procedure divrem ( x, y : internal ; var q, r : internal  ) ;
  860.  
  861.         (* Computes q := x DIV y and r := x REM y.  *)
  862.  
  863. procedure dodivrem ;
  864.  
  865.         (* Computes DIV and REM for normalized y and normalized or
  866.         unnormalized x.  *)
  867.         
  868. var
  869. i,j : integer ;
  870. carry, sbit, tbit, zbit : boolean ;
  871. rlast, ylast  : integer ;
  872. nc : integer ;
  873. roundup : boolean ;
  874.  
  875. begin
  876.         (* Preround. *)
  877. roundkcs( x, fpstatus.mode.round, xprec) ;
  878. roundkcs( y, fpstatus.mode.round, xprec) ;
  879. makezero(q) ; (* Starting assumption.  *)
  880. r := x ; (* Starting assumption.  *)
  881. nc := x.exponent - y.exponent + 1 ; (* Number of cycles to produce result. *)
  882. if nc >= 0 then begin
  883. ylast := lastbit ( y, 0, leastsigbit ) ;
  884. rlast := lastbit ( x, 0, leastsigbit ) + 1 ;
  885. if rlast < (ylast+1) then rlast := ylast + 1  ;
  886.  
  887. for i := 0 to (rlast-1) do 
  888. r.significand[i+1] := x.significand[i] ; (* remainder R := X/2 *)
  889. r.significand[0] := false ;
  890. sbit := false ; (* Sbit contains the sign of the remainder between steps *)
  891.  
  892. for i := 1 to nc do begin (* for each bit of result *)
  893. tbit := sbit ; (* T bit holds test to decide + or -.  *)
  894. sbit := r.significand[ylast+1] ;
  895. for j := (ylast+1) to (rlast-1) do
  896. r.significand[j] := r.significand[j+1] ;
  897. carry := false ;
  898.  
  899. if tbit then begin (* If R < 0 then R := 2R+Y *)
  900. for j := ylast downto 0 do begin
  901. adder(sbit, y.significand[j], tbit, carry) ;
  902. sbit := r.significand[j] ;
  903. r.significand[j] := tbit ;
  904. end ;
  905. adder( sbit, false, sbit, carry) ; (* Sbit now has the sign of R *)
  906. end
  907. else begin (* If R >= 0 then R := 2R-Y *)
  908. for j := ylast  downto 0 do begin
  909. suber(sbit, y.significand[j], tbit, carry) ;
  910. sbit := r.significand[j] ;
  911. r.significand[j] := tbit ;
  912. end ;
  913. suber(sbit, false, sbit, carry) ; (* Sbit now has the sign of R *)
  914. end ;
  915. r.significand[rlast] := false ; (* result of left shift *)
  916. if (leastsigbit-nc+i) >= 0 then 
  917. q.significand[leastsigbit-nc+i] := not sbit ;
  918. end ;
  919.  
  920. r.exponent := r.exponent - nc + 1  ; 
  921. for i := 0 to (leastsigbit-nc) do 
  922. q.significand[i] := false ;  (* Fill in bits.  *)
  923. carry := false ;
  924. if sbit then (* R < 0 so set R := R + Y.  *)
  925. for j := rlast downto 0 do
  926. adder(r.significand[j], y.significand[j], r.significand[j], carry ) ;
  927. if  zerofield( r, 0, rlast) then
  928.         (* R=0 so q is exact and r is zero.  *)
  929.         makezero(r) 
  930.         else begin (* At this point
  931.         2R < Y implies q is ok
  932.         2R = Y implies round q to even and set r to +- .5 Y
  933.         Y < 2R < 2Y implies round q upward, set r to r-y.  *)
  934. roundup := false ; (* Roundup controls rounding of q, and thus r.  *)
  935. carry := false ;
  936. zbit := false ;
  937. for j := rlast downto 1 do begin (* Compute sign of 2R - Y .*)
  938. suber(r.significand[j], y.significand[j-1], tbit, carry ) ;
  939. zbit := zbit or tbit ;
  940. end ;
  941. suber(r.significand[0], false, tbit, carry ) ;
  942. zbit := zbit or tbit ; (* zbit is false if 2R = Y.  *)
  943. if not carry then begin (* 2R >= Y.  *)
  944. roundup := zbit (* 2R>Y *) or q.significand[leastsigbit] (* 2R=Y *) ;
  945. end ;
  946. if roundup then begin (* Increment q; reverse r.  *)
  947. carry := true ;
  948. for j := leastsigbit downto 0 do
  949. adder(q.significand[j], false, q.significand[j], carry) ;
  950. carry := false ;
  951. for j := (leastsigbit+1) downto 0 do
  952. suber( y.significand[j], r.significand[j], r.significand[j], carry ) ;
  953.         (* R := Y - R.  *)
  954. r.sign := not r.sign ;
  955. end end ;
  956. donormalize(r) ;
  957. q.exponent := 64 ;
  958. donormalize(q) ;
  959. end ;
  960. end ;
  961.  
  962. begin (* divrem *)
  963.  
  964. if (abs(kind(x))=nankind) or (abs(kind(y))=nankind) then begin
  965. picknan( x, y, q ) ;
  966. r := q ;
  967. end 
  968. else 
  969.         begin (* no nan *)
  970.         donormalize(x) ; (* Rem always normalizes x. *)
  971.         case abs(kind(y)) of
  972.  
  973. zerokind, unnormkind : begin
  974. makenan( nanrem, q ) ;
  975. r := q ;
  976. end ;
  977.  
  978. normkind : case abs(kind(x)) of
  979. zerokind : begin
  980. makezero(q) ;
  981. r := x ;
  982. end ;
  983. unnormkind, normkind : dodivrem ;
  984. infkind : begin
  985. q := x ;
  986. makenan( nanrem, r) ;
  987. end ;
  988. end ;
  989.  
  990. infkind : case abs(kind(x)) of
  991. ;zerokind, normkind : begin
  992. makezero(q) ;
  993. r := x ;
  994. end ;
  995. infkind : begin
  996. q := x ;
  997. makenan( nanrem, r) ;
  998. end end end ;
  999.         end   (* not nan *) ;
  1000. q.sign := x.sign <> y.sign ; (* EXOR. *)
  1001. end ;
  1002.  
  1003.  
  1004. End-Of-File
  1005. echo ""
  1006. echo "End of Kit"
  1007. exit
  1008.  
  1009.