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

  1. From: genrad!decvax!decwrl!sun!dgh!dgh (David Hough)
  2. Subject: IEEE Calculator (part 5 of 6)
  3. Newsgroups: mod.sources
  4. Approved: jpn@panda.UUCP
  5.  
  6. Mod.sources:  Volume 3, Issue 7
  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 extra.i
  13. cat >extra.i <<'End-Of-File'
  14.  
  15. (* File extra.i, version 9 October 1984 *)
  16.  
  17. procedure csqrt ( x : internal ; var z : internal  ) ;
  18.  
  19.         (* Computes z := sqrt(x).  *)
  20.         
  21. procedure dosqrt ;
  22.  
  23.         (* Does SQRT for normalized positive x.  *)
  24.  
  25. var
  26. i, j : integer ;
  27. r : internal ;
  28. carry : boolean ;
  29. sbit, vbit, orbit : boolean ;
  30.  
  31. begin
  32. roundkcs ( x, fpstatus.mode.round, xprec ) ; (* Pre-round.  *)
  33. r := x ; (* R will be the remainder for the nonrestoring binary square root  *)
  34. z.sign := false ; (* Result is never negative since x is positive donormalize  *)
  35. if odd(r.exponent) then begin
  36. r.exponent := r.exponent + 1 ; (* Make exponent even.  *)
  37. right( r, 1 ) ; (* And make fraction 0.25 <= r <= 0.5  *)
  38. end ;
  39. z.exponent := r.exponent div 2 ;
  40. sbit := false ; (* Sign bit of remainder, initially positive.  *)
  41. carry := false  ;
  42.                 (* Subtract 0.25 to start the fun.  *)
  43. suber(r.significand[1], true, r.significand[1], carry) ;
  44. suber(r.significand[0], false, r.significand[0], carry) ;
  45.  
  46.                 (* Now do main loop.
  47.                 Ri fits in i+1 bits.
  48.                 Zi fits in i-1 bits.  *)
  49.  
  50. for i := 1 to (leastsigbit+2) do
  51. if sbit then begin (* R is negative so add: 
  52.                         Zi+1 := 2 Zi
  53.                         Ri+1 := 4 Ri + 4 Zi+1 + 3    *)
  54. z.significand[i-1] := false ; (* Set result bit.  *)
  55. vbit := r.significand[0] ;  (* Catch overfl.  *)
  56. left(r,1) ; (* Multiply R by 2.  *)
  57. carry := false ;
  58. adder( r.significand[i+1], true, r.significand[i+1], carry) ; 
  59. (* Add 3*2**-i-2 *)
  60. adder(r.significand[i], true, r.significand[i], carry) ;
  61. for j := (i-1) downto 0 do (* Add Zi+1.  *)
  62. adder(r.significand[j], z.significand[j], r.significand[j], carry ) ;
  63. adder( vbit, false, vbit, carry ) ;
  64. adder ( sbit, false, sbit, carry ) ; (* Sets sign of r.  *)
  65. end
  66.  
  67. else begin (* R is >= 0 so subtract:
  68.                         Zi+1 := 2 Zi + 1 
  69.                         Ri+1 := 4 Ri - 4 Zi+1 - 1   *)
  70. z.significand[i-1] := true ; (* Set result bit.  *)
  71. vbit := r.significand[0] ;
  72. left(r,1) ;
  73. carry := false ;
  74. suber( r.significand[i+1], true, r.significand[i+1], carry ) ;
  75.         (* Subtract 1 *)
  76. suber(r.significand[i], false, r.significand[i], carry ) ;
  77. for j := (i-1) downto 0 do (* Subtract Zi+1 *)
  78. suber( r.significand[j], z.significand[j], r.significand[j], carry ) ;
  79. suber( vbit, false, vbit, carry ) ;
  80. suber( sbit, false, sbit, carry ) ;
  81. end ;
  82.  
  83. z.significand[stickybit-1] := false ; (* This bit isn't used.  *)
  84.  
  85.         (* Determine sticky bit.  Z is exact iff
  86.         Rn + 4 Zn + 1 <= 0   *)
  87.         
  88. carry := false ; orbit := false ;
  89. adder( r.significand[leastsigbit+3], true, vbit, carry ) ; (* Add 1.  *)
  90. orbit := orbit or vbit ;
  91. adder( r.significand[leastsigbit+2], false, vbit, carry ) ;
  92. orbit := orbit or vbit ;
  93. for j := (leastsigbit+1) downto 0 do begin
  94. adder( r.significand[j], z.significand[j], vbit, carry ) ;
  95. orbit := orbit or vbit ;
  96. end ;
  97. adder(sbit, false, vbit, carry ) ;
  98. orbit := orbit or vbit ;
  99. adder( sbit, false, sbit, carry ) ;
  100. z.significand[stickybit] := orbit and (not sbit) ;
  101.                 (* Inexact if result of test is positive.  *)
  102. end ;
  103.  
  104.  
  105. begin (* csqrt*)
  106.  
  107. case kind(x) of 
  108. negnan, nankind : z := x ;
  109. neginf, negnorm, negunnorm, unnormkind : makenan(nansqrt, z) ;
  110. zerokind : z := x ;
  111. normkind : dosqrt ;
  112. infkind : if fpstatus.mode.clos = affine then z := x else
  113. makenan(nansqrt, z ) ;
  114. otherwise
  115. end ;
  116.  
  117. end ;
  118.  
  119. procedure clogb ( x : internal ; var z : internal ) ;
  120.  
  121.         (* Sets y to the unbiased exponent of x.  *)
  122.         
  123. var
  124. yi : cint64 ;
  125. i, k : integer ;
  126.  
  127. begin 
  128. case abs(kind(x)) of
  129.  
  130. zerokind : begin
  131. makeinf(z) ;
  132. z.sign := true ;
  133. end ;
  134.  
  135. unnormkind, normkind : begin
  136. for i := 0 to 5 do yi[i] := 0 ;
  137. k := x.exponent - 1 ; (* -1 because binary point is to left of bit 0.  *)
  138. yi[6] := abs(k) div 256 ;
  139. yi[7] := abs(k) mod 256 ;
  140. unpackinteger ( yi, z, i16 ) ;
  141. z.sign := k < 0 ;
  142. end ;
  143.  
  144. infkind : begin
  145. makeinf(z) ;
  146. z.sign := false ;
  147. end ;
  148.  
  149. nankind : z := x ;
  150. otherwise
  151. end ;
  152. end ;
  153.  
  154. procedure cnextafter ( x, y : internal ; var z : internal  ) ;
  155.  
  156.         (* Sets z to the next machine number after x in the direction of
  157.         y.  *)
  158.  
  159. var
  160. cc : conditioncode ;
  161. i : integer ;
  162. rnd : roundtype ;
  163. moveright : boolean ;
  164. t : internal ;
  165.  
  166. begin
  167. roundkcs(x, fpstatus.mode.round, xprec ) ; (* Preround.  *)
  168. roundkcs(y, fpstatus.mode.round, xprec ) ;
  169. z := x ; (* Default result.  *)
  170. compare( x, y, cc ) ;
  171. if cc in [lesser,greater] then
  172.         begin (* x <> y *)
  173.         moveright := cc = lesser ; (* If x < y then move x to right (+INF) *)
  174.         rnd := fpstatus.mode.round ;
  175.         if moveright then fpstatus.mode.round := rpos else
  176.                 fpstatus.mode.round := rneg ;
  177.         case abs(kind(x)) of
  178.         zerokind : begin (* zero *)
  179.                    z.significand[leastsigbit] := true ;
  180.                    z.sign := not moveright ;
  181.                    end   (* zero *) ;
  182.         infkind :  begin (* inf *)
  183.                    z.exponent := maxexp - 1 ;
  184.                    for i := 0 to leastsigbit do z.significand[i] := true ;
  185.                    z.sign := moveright ;
  186.                    end   (* inf *) ;
  187.         unnormkind, normkind :
  188.                 if unzero(x) then z.exponent := x.exponent - 1
  189.         else
  190.                 begin (* Do add *)
  191.                 makezero(t) ;
  192.                 t.significand[leastsigbit] := true ;
  193.                 t.sign := not moveright ;
  194.                 add(x, t, z) ;
  195.                 end   (* Do add *) ;
  196.         otherwise
  197.     end (* case *) ;
  198.         roundkcs( z, fpstatus.mode.round, fpstatus.mode.precision ) ;
  199.         store(z) ;
  200.      fpstatus.mode.round := rnd ; (* Force special rounding mode on store.  *)
  201.         end   (* x <> y *) ;
  202. fpstatus.curexcep := fpstatus.curexcep - [inxact] ; (* Don't want inxact
  203.         on a NEXT operation.  *)
  204. end ;
  205.  
  206.  
  207. procedure complement ( var x : internal ; var v : boolean ) ;
  208.  
  209.         (* Complements x.significand, treating it as a 64 bit integer.
  210.         v is a carry out bit.  *)
  211.  
  212. var 
  213. carry : boolean ;
  214. i : integer ;
  215.  
  216. begin
  217. carry := false ;
  218. for i := leastsigbit downto 0 do 
  219. suber( false, x.significand[i], x.significand[i], carry ) ;
  220. v := carry ;
  221. end ;
  222.  
  223. procedure cscale ( x, y : internal ; var z : internal  ) ;
  224.  
  225.         (* Sets z to x * 2 **int(y).  *)
  226.         
  227. var
  228. rx, ry : roundtype ;
  229.  
  230. procedure doscale ; 
  231.  
  232.         (* Carries out scaling for proper x and y.  *)
  233.         
  234. var
  235. xe : internal ;
  236. i, k : integer ;
  237. v, v2, carry : boolean ;
  238. s : strng ;
  239. irs : integer ;
  240.  
  241. begin
  242. z := x ; (* Now all we have to do is set the exponent.  *)
  243. xe.sign := x.exponent < 0 ; (* xe will contain exponent of x expanded.  *)
  244. k := abs(x.exponent) ;
  245. for i := leastsigbit downto 0 do begin
  246. xe.significand[i] := odd(k) ;
  247. k := k div 2   ;
  248. end ;
  249.  
  250. if xe.sign then complement( xe, v2 ) ;
  251.  
  252. if y.exponent > 64 then begin (* Substitute for huge y.  *)
  253. y.exponent := 64 ;
  254. y.significand[0] := true ;
  255. end ;
  256. if y.exponent < (64-stickybit) then irs := stickybit 
  257.         (* Look out for 16 bit integer overfl.  *)
  258. else irs := 64 - y.exponent ; (* Set up count for right shift.  *)
  259. right( y, irs  ) ; (* Align significand of y as an integer.  *)
  260. if y.sign then complement(y, v) ;
  261. carry := false ;
  262. for i := stickybit downto 0 do 
  263. adder( xe.significand[i], y.significand[i], xe.significand[i], carry ) ;
  264. adder( v, v2, xe.sign, carry ) ;
  265.  
  266. if xe.sign then complement( xe, v ) ;
  267.  
  268. v := not zerofield( xe, 0, 48 ) ; (* v is now an overfl flag.  *)
  269. k := 0 ;
  270. for i := 49 to leastsigbit do begin
  271. k := k + k ;
  272. if xe.significand[i] then k := k + 1 ;
  273. end ;
  274. if xe.sign then k := -k ; (* Set up correct negative exponent.  *)
  275. v := v or (k=maxexp) or (k=minexp) ;
  276. if v then begin (* Exponent overfl.  *)
  277. if xe.sign then begin (* Floating underfl.  *)
  278. makezero(z) ;
  279. setex ( underfl ) ;
  280. end 
  281. else begin (* Floating overfl.  *)
  282. makeinf(z) ;
  283. setex ( overfl ) ;
  284. end
  285. end
  286. else z.exponent := k ;
  287. end ;
  288.  
  289. begin (* Scale.  *)
  290. if (abs(kind(x))=nankind) or (abs(kind(x))=nankind) then 
  291. picknan(x, y, z ) else begin
  292. rx := fpstatus.mode.round ; (* Default.  *)
  293. ry := rx ;
  294. case rx of
  295. rneg : if x.sign then ry := rpos ;
  296. rpos : if x.sign then ry := rneg ;
  297. rzero : ry := rneg ;
  298. otherwise
  299. end ;
  300.  
  301. roundkcs(x, rx, xprec) ;
  302. roundint(y, ry, xprec) ;
  303. donormalize(y) ;
  304.  
  305. case abs(kind(x)) of
  306.  
  307. zerokind : case abs(kind(y)) of
  308.  
  309. zerokind, normkind : z := x ;
  310. infkind : if (fpstatus.mode.clos = affine) and
  311. (kind(y) = neginf) then z := x else
  312. makenan( nanmul, z) ; (* 2 **INF = NAN,  2**+INF = +INF, 2**-INF = 0 *)
  313. end ;
  314.  
  315. unnormkind, normkind : case abs(kind(y)) of
  316. zerokind, normkind : doscale ;
  317. infkind : if fpstatus.mode.clos = proj then makenan(nanmul, z)
  318. else if x.sign then makezero(z)
  319. else makeinf(z) ;
  320. end ;
  321.  
  322. infkind : case abs(kind(y)) of
  323. zerokind, normkind : z := x ;
  324. infkind : if (fpstatus.mode.clos=proj) or (kind(x)=neginf) then
  325. makenan(nanmul, z)
  326. else z := x ;
  327. end ;
  328.  
  329. otherwise
  330. end ;
  331. z.sign := x.sign ;
  332. end ;
  333. end ;
  334.  
  335.  
  336. End-Of-File
  337. echo Extracting storage.i
  338. cat >storage.i <<'End-Of-File'
  339. (* File storage.i, Version 9 October 1984.  *)
  340.  
  341. function xbyte ( x : internal ; p1, p2 : integer ) : BYT ;
  342.  
  343.         (* Converts bits
  344.         x.significand[p1..p2] 
  345.         into a BYT value.  *)
  346.         
  347. var
  348. b : BYT ;
  349. i : integer ;
  350.  
  351. begin
  352. b := 0 ;
  353. for i := p1 to p2 do 
  354. if x.significand[i] then b := b + b + 1 else b := b + b ;
  355. xbyte := b ;
  356. end ;
  357.  
  358. procedure ibytes ( k : integer ; var b1, b2 : BYT ) ;
  359.  
  360.         (* Converts 16 bit integer into two BYT values.  *)
  361.         
  362. var 
  363. neg : boolean ;
  364.  
  365. begin
  366. neg := k < 0 ;
  367. if neg then k := ( k + 16384 ) + 16384  ; (* Remove most significant bit.  *)
  368. b1 := k div 256 ;
  369. b2 := k mod 256 ;
  370. if neg then b1 := b1 + 128 ; (* Restore most significant bit.  *)
  371. end ;
  372.  
  373. procedure bytehex ( b : BYT  ; var s  : strng )  ;
  374.  
  375.         (* Converts BYT to two hex digits.  *)
  376.         
  377. var
  378. nib : nibarray ;
  379. i,j : integer ;
  380. w : BYT ;
  381.  
  382. begin
  383. s[0] := chr(2) ;
  384. w := b ;
  385. for j := 2 downto 1 do begin
  386. for i := 3 downto 0 do begin
  387. nib[i] := odd(w) ;
  388. w := w div 2 ;
  389. end ;
  390. s[j] := nibblehex(nib) ;
  391. end ;
  392. end ;
  393.  
  394. procedure bytex ( b : BYT ; var x : internal ; p1, p2 : integer ) ;
  395.  
  396.         (* Inserts BYT b into
  397.         x.significand[p1..p2] *)
  398.         
  399. var i : integer ;
  400.  
  401. begin
  402. for i := p2 downto p1 do begin
  403. x.significand[i] := odd(ord(b)) ;
  404. b := b div 2 ;
  405. end ;
  406. end ;
  407.  
  408. procedure unpackextended ( y : cextended ; var x : internal ) ;
  409.  
  410.         (* Unpacks cextended into internal.  *)
  411.         
  412. var
  413. zero : boolean ;
  414. i : integer ;
  415.  
  416. begin
  417. x.sign := (y[0] >= 128) ;
  418. if x.sign then y[0] := y[0] - 128 ; (* Remove sign bit.  *)
  419. x.exponent := (256*y[0] + y[1]) - biasex ;
  420. for i := 2 to 9 do bytex( y[i], x, (8*i-16), (8*i-9) ) ;
  421. for i := (leastsigbit+1) to stickybit do 
  422. x.significand[i] := false ;
  423.  
  424. if x.exponent >= maxex then x.exponent := maxexp ; (* INF/NAN *)
  425. if x.exponent <= minex then begin
  426. zero := y[2]=0 ;
  427. for i := 3 to 9 do 
  428. zero := zero and (y[i]=0) ;
  429. if zero then x.exponent := minexp else begin
  430. x.exponent := minex + 1 ;
  431.         (* Add offset for cextended denormalized.  *)
  432. if (fpstatus.mode.norm = normalizing)  then begin
  433. donormalize(x) ;
  434. end
  435.         (* Normalize denormalized operand in normalizing mode.  *)
  436. end
  437. end ;
  438.  
  439. end ;
  440.  
  441. procedure toextended ( var x : internal ; var y : cextended  ) ;
  442.         
  443.         (* Converts x to cextended y.  *)
  444.         
  445. var i : integer ;
  446. s : strng ;
  447. special : boolean ;
  448. y0,y1 : BYT ;
  449.  
  450. begin
  451. case abs(kind(x)) of
  452. otherwise ;
  453. zerokind : x.exponent := minex ;
  454.  
  455. unnormkind, normkind : begin
  456. if x.exponent <= minex then begin (* Underflow.  *)
  457. if underfl in fpstatus.trap then begin (* Trap enabled.  *)
  458. setex ( underfl ) ;
  459. x.exponent := x.exponent + 24576 ;
  460. if x.exponent <= minex then begin (* Severe underfl - give invalid result. *)
  461. makenan(nanresult,x) ;
  462. end ;
  463. end
  464. else begin (* Trap disabled.  *)
  465. right( x, minex + 1   - x.exponent ) ;
  466. x.exponent := minex ;
  467. roundkcs( x, fpstatus.mode.round, fpstatus.mode.precision ) ;
  468. if inxact in fpstatus.curexcep  then
  469.         setex ( underfl ) ; (* Signal.  *)
  470. end ;
  471. end ;
  472.  
  473. roundkcs( x, fpstatus.mode.round, fpstatus.mode.precision ) ;
  474. if (x.exponent >= maxex)  then begin (* Overflow.  *)
  475. if overfl in fpstatus.trap then begin (* Trap enabled.  *)
  476. setex ( overfl ) ;
  477. x.exponent := x.exponent - 24576 ;
  478. if x.exponent >= maxex then (* Severe overfl - give invalid result.  *)
  479. begin
  480. makenan(nanresult,x) ;
  481. end ;
  482. end
  483.  
  484. else begin (* Trap disabled.  *)
  485. setex ( inxact ) ;
  486. setex( overfl ) ;
  487. case fpstatus.mode.round of
  488. rneg : special := not x.sign ;
  489. rpos : special := x.sign ;
  490. rnear : special := false ;
  491. rzero : special := true ;
  492. otherwise 
  493. end ;
  494. if special then begin (* Special case roundings.  *)
  495. x.exponent := maxex - 1 ; 
  496.         (* Round normalized to largest normalized number.
  497.         Round unnormalized to largest exponent, same significand.  *)
  498. if x.significand[0] then 
  499. for i := 0 to leastsigbit do x.significand[i] := true ;
  500. end
  501. else begin (* Normal case - set INF.  *)
  502. x.exponent := maxex ;
  503. for i := 0 to leastsigbit do x.significand[i] := false ;
  504. end ;
  505. end
  506. end ;
  507. if abs(kind(x)) = nankind then begin
  508. setex(invop) ;
  509. fpstatus.curexcep := fpstatus.curexcep - [inxact] ;
  510. x.exponent := maxex ;
  511. end end ;
  512.  
  513. infkind, nankind : x.exponent := maxex ;
  514. end ;
  515.  
  516. for i := 2 to 9 do (* Pack significand.  *)
  517. y[i] := xbyte ( x, (8*i-16), (8*i-9) ) ;
  518. ibytes ( x.exponent + biasex, y0, y1 ) ; (* Pack exponent.  *)
  519. y[0] := y0 ; y[1] := y1 ;
  520. if x.sign then y[0] := y[0] + 128 ; (* Pack sign bit.  *)
  521.  
  522. write(' Extended format: ') ;
  523. for i := 0 to 9 do begin 
  524. bytehex( y[i], s ) ;
  525. write(s[1],s[2], ' ') ;
  526. end ;
  527. writeln ;
  528.  
  529. unpackextended ( y, x) ;
  530.  
  531. end ;
  532.  
  533. procedure unpackdouble (* y : cdouble ; var x : internal *) ;
  534.  
  535.         (* Unpacks cdouble into internal.  *)
  536.         
  537. var
  538. i : integer ;
  539. zero : boolean ;
  540.  
  541. begin
  542. x.sign := y[0] >= 128 ;
  543. if x.sign then y[0] := y[0] - 128 ;
  544. x.exponent := (16*y[0] + (y[1] div 16)) - biased ;
  545. bytex ( y[1] mod 16, x, 1, 4 ) ;
  546. for i := 2 to 7 do bytex ( y[i], x, (8*i-11), (8*i-4) ) ;
  547. for i := 53 to stickybit do x.significand[i] := false ;
  548.  
  549. if x.exponent >= maxed then begin
  550. x.exponent := maxexp ;
  551. x.significand[0] := false ;
  552. end
  553. else if x.exponent <= mined then  begin
  554. x.significand[0] := false ;
  555. if zerofield( x, 1, 52 ) then x.exponent := minexp (* Normal Zero.  *)
  556. else x.exponent := x.exponent + 1 ; (* Offset for denormalized numbers.  *)
  557. if (fpstatus.mode.norm = normalizing)  then donormalize(x) 
  558.         (* Normalize denormalized operand in normalizing mode.  *)
  559. end 
  560. else x.significand[0] := true ; (* Insert leading bit. *)
  561. end ;
  562.  
  563. procedure todouble (* var x : internal ; var y : cdouble  *) ;
  564.  
  565.         (* Converts x to cdouble y.  *)
  566.         
  567. var
  568. i : integer ;
  569. s : strng ;
  570. special : boolean ;
  571. y0,y1 : BYT ;
  572.  
  573. begin
  574. case abs(kind(x)) of
  575. otherwise ;
  576. zerokind : x.exponent := mined ;
  577.  
  578. unnormkind, normkind : begin
  579. if x.exponent <= mined then begin (* Underflow.  *)
  580. if underfl in fpstatus.trap then begin (* Trap enabled.  *)
  581. setex ( underfl ) ;
  582. x.exponent := x.exponent + 1536 ;
  583. if( x.exponent <= mined) or not x.significand[0]  then begin (* Severe underfl.  *)
  584. makenan(nanresult,x)
  585. end ;
  586. end
  587. else begin (* Trap disabled.  *)
  588. right( x, mined + 1 - x.exponent ) ;
  589. x.exponent := mined+1 ;
  590. roundkcs( x, fpstatus.mode.round, dprec ) ;
  591. if inxact in fpstatus.curexcep  then setex ( underfl ) ; (* Signal.  *)
  592. end ;
  593. end ;
  594.  
  595. roundkcs( x, fpstatus.mode.round, dprec ) ;
  596. if (x.exponent >= maxed) and x.significand[0] then begin (* Overflow.  *)
  597. if overfl in fpstatus.trap then begin (* Trap enabled.  *)
  598. setex ( overfl ) ;
  599. x.exponent := x.exponent - 1536 ;
  600. if x.exponent >= maxed then begin (* Severe overfl.  *)
  601. makenan(nanresult,x)
  602. end ;
  603. end
  604.  
  605. else begin (* Trap disabled.  *)
  606. setex ( inxact ) ;
  607. setex( overfl ) ;
  608. case fpstatus.mode.round of
  609. rneg : special := not x.sign ;
  610. rpos : special := x.sign ;
  611. rnear : special := false ;
  612. rzero : special := true ;
  613. otherwise
  614. end ;
  615. if special then begin (* Special case roundings.  *)
  616. x.exponent := maxed - 1 ; (* Round to largest normalized number.  *)
  617. for i := 0 to leastsigbit do x.significand[i] := true ;
  618. end
  619. else begin (* Normal case - set INF.  *)
  620. x.exponent := maxed ;
  621. for i := 0 to leastsigbit do x.significand[i] := false ;
  622. end ;
  623. end
  624. end ;
  625.  
  626. if (x.exponent=(mined+1)) and (not x.significand[0]) then
  627.         x.exponent := mined ; (* Look for  denormalized number,
  628.          which may have resulted from an underfl, but might not have.  *)
  629.  
  630. if (abs(kind(x))=nankind) or (  (x.exponent > mined) and (x.exponent < maxed) 
  631. and not x.significand[0]) then begin 
  632. (* Invalid Result.  *)
  633. makenan( nanresult, x ) ;
  634. setex ( invop ) ;
  635. fpstatus.curexcep := fpstatus.curexcep - [  inxact ] ;
  636. x.exponent := maxed ;
  637. end ;
  638. end ;
  639.  
  640. infkind, nankind : 
  641.         begin (* inf/nan *)
  642.         x.exponent := maxed ;
  643.         for i := 53 to leastsigbit do
  644.                 if x.significand[i] then x.significand[52] := true ;
  645.                 (* OR together least significant bits of NAN *)
  646.         end   (* inf/nan *) ;
  647. end (* case *);
  648.  
  649. ibytes (( x.exponent + biased) * 16, y0, y1 ) ;
  650.         (* Pack exponent *)
  651. y[0] := y0 ; y[1] := y1 ;
  652. if x.sign then y[0] := y[0] + 128 ; (* Pack sign.  *)
  653. y[1] := y[1] + xbyte( x, 1, 4 ) ;
  654. for i := 2 to 7 do 
  655. y[i] := xbyte ( x, 8 * i - 11, 8 * i - 4 ) ; (* Pack significand.  *)
  656.  
  657. write(' Double format: ') ;
  658. for i := 0 to 7 do begin
  659. bytehex( y[i], s ) ;
  660. write(s[1],s[2], ' ') ;
  661. end ;
  662. writeln ;
  663.  
  664. unpackdouble( y, x ) ;
  665. end ;
  666.  
  667. procedure unpacksingle (* y : csingle ; var x : internal *) ;
  668.  
  669.         (* Unpacks csingle into internal.  *)
  670.         
  671. var
  672. i : integer ;
  673. zero : boolean ;
  674.  
  675. begin
  676. x.sign := y[0] >= 128 ;
  677. if x.sign then y[0] := y[0] - 128 ;
  678. x.exponent := (2*y[0] + (y[1] div 128)) - biases ;
  679. bytex ( y[1] mod 128, x, 1, 7 ) ;
  680. for i := 2 to 3 do bytex ( y[i], x, (8*i-8), (8*i-1) ) ;
  681. for i := 24 to stickybit do x.significand[i] := false ;
  682.  
  683. if x.exponent >= maxes then begin
  684. x.exponent := maxexp ;
  685. x.significand[0] := false ;
  686. end
  687. else if x.exponent <= mines then  begin
  688. x.significand[0] := false ;
  689. if zerofield( x, 1, 23 ) then x.exponent := minexp (* Normal Zero.  *)
  690. else x.exponent := x.exponent + 1 ; (* Offset for denormalized numbers.  *)
  691. if (fpstatus.mode.norm = normalizing)   then donormalize(x) 
  692.         (* Normalize denormalized operand in normalizing mode.  *)
  693. end 
  694. else x.significand[0] := true ; (* Insert leading bit. *)
  695. end ;
  696.  
  697. procedure tosingle (* var x : internal ; var y : csingle  *) ;
  698.  
  699.         (* Converts x to csingle y.  *)
  700.         
  701. var
  702. i : integer ;
  703. s : strng ;
  704. special : boolean ;
  705. y0,y1 : BYT ;
  706.  
  707. begin
  708. case abs(kind(x)) of
  709. otherwise ;
  710. zerokind : x.exponent := mines ;
  711.  
  712. unnormkind, normkind : begin
  713. if x.exponent <= mines then begin (* Underflow.  *)
  714. if underfl in fpstatus.trap then begin (* Trap enabled.  *)
  715. setex ( underfl ) ;
  716. x.exponent := x.exponent + 192 ;
  717. if (  x.exponent <= mines) or (not x.significand[0])
  718. then begin (* Severe underfl.  *)
  719. makenan(nanresult,x) ;
  720. end ;
  721. end
  722. else begin (* Trap disabled.  *)
  723. right( x, mines + 1 - x.exponent ) ;
  724. x.exponent := mines+1 ;
  725. roundkcs( x, fpstatus.mode.round, sprec ) ;
  726. if inxact in fpstatus.curexcep  then setex ( underfl ) ; (* Signal.  *)
  727. end ;
  728. end ;
  729.  
  730. roundkcs( x, fpstatus.mode.round, sprec ) ;
  731. if (x.exponent >= maxes) and x.significand[0] then begin (* Overflow.  *)
  732. if overfl in fpstatus.trap then begin (* Trap enabled.  *)
  733. setex ( overfl ) ;
  734. x.exponent := x.exponent - 192 ;
  735. if x.exponent >= maxes then begin (* Severe overfl.  *)
  736. makenan(nanresult,x) ;
  737. end ;
  738. end
  739.  
  740. else begin (* Trap disabled.  *)
  741. setex ( inxact ) ;
  742. setex( overfl ) ;
  743. case fpstatus.mode.round of
  744. rneg : special := not x.sign ;
  745. rpos : special := x.sign ;
  746. rnear : special := false ;
  747. rzero : special := true ;
  748. otherwise 
  749. end ;
  750. if special then begin (* Special case roundings.  *)
  751. x.exponent := maxes - 1 ; (* Round to largest normalized number.  *)
  752. for i := 0 to leastsigbit do x.significand[i] := true ;
  753. end
  754. else begin (* Normal case - set INF.  *)
  755. x.exponent := maxes ;
  756. for i := 0 to leastsigbit do x.significand[i] := false ;
  757. end ;
  758. end
  759. end ;
  760. if  ( (x.exponent=(mines+1)) and (not x.significand[0]))
  761. then
  762.         x.exponent := mines ; (* Look for  denormalized number.  *)
  763.  
  764. if (abs(kind(x))=nankind) or (  (x.exponent > mines) and (x.exponent < maxes) 
  765. and not x.significand[0] )  then begin 
  766.         (* Invalid Result.  *)
  767.         makenan( nanresult, x ) ;
  768.         setex ( invop ) ;
  769.         fpstatus.curexcep := fpstatus.curexcep - [inxact] ;
  770.         x.exponent := maxes ;
  771.         end ;
  772.         end ;
  773.  
  774. infkind, nankind : 
  775.         begin (* inf/nan *)
  776.         x.exponent := maxes ;
  777.         for i := 24 to leastsigbit do
  778.                 if x.significand[i] then x.significand[23] := true ;
  779.                 (* OR together least significant bits of NAN *)
  780.         end   (* inf/nan *) ;
  781. end (* case *);
  782.  
  783. ibytes (( x.exponent + biases) * 128, y0, y1 ) ;
  784.         (* Pack exponent *)
  785. y[0] := y0 ; y[1] := y1 ;
  786. if x.sign then y[0] := y[0] + 128 ; (* Pack sign.  *)
  787. y[1] := y[1] + xbyte( x, 1, 7 ) ;
  788. for i := 2 to 3 do 
  789. y[i] := xbyte ( x, 8 * i - 8 , 8 * i - 1 ) ; (* Pack significand.  *)
  790.  
  791. write(' Single format: ') ;
  792. for i := 0 to 3 do begin
  793. bytehex( y[i], s ) ;
  794. write(s[1],s[2], ' ') ;
  795. end ;
  796. writeln ;
  797.  
  798. unpacksingle( y, x ) ;
  799. end ;
  800.  
  801. procedure unpackinteger (* y : cint64 ; var x : internal ; itype : inttype *) ;
  802.         
  803.         (* Unpacks integer in y according to itype.
  804.         The significant bytes are presumed to be on the right.  *)
  805.         
  806. var i, msy : integer ;
  807. carry : boolean ;
  808. es : excepset ;
  809.  
  810. begin
  811. case itype of 
  812. i16 : msy := 6 ;
  813. i32 : msy := 4 ;
  814. i64 : msy := 0 ;
  815. otherwise
  816. end ;
  817. x.sign := y[msy] >= 128 ;
  818. if x.sign then (* Expand negative.  *)
  819. for i := 0 to (msy-1) do y[i] := 255 
  820. else
  821. for i := 0 to (msy-1) do y[i] := 0 ;
  822. for i := 0 to 7 do bytex( y[i], x, 8*i, 8*i+7) ;
  823. if x.sign then begin
  824. carry := false ;
  825. for i:= leastsigbit downto 0 do 
  826. suber( false, x.significand[i], x.significand[i], carry ) ;
  827. end ;
  828. for i := (leastsigbit+1) to stickybit do x.significand[i] := false ;
  829. x.exponent := 64 ;
  830. donormalize(x) ;
  831. if (itype = i64) and (x.exponent = 64) then
  832.         begin (* It was really a NAN *)
  833.         es := fpstatus.curexcep ;
  834.         makenan(naninteger, x) ;
  835.         x.sign := false ; (* Default is a positive NAN.  *)
  836.         fpstatus.curexcep := es ; (* Don't let makenan set NV.  *)
  837.         end   (* It was really a NAN *) ;
  838. end ;
  839.  
  840. procedure tointeger ( itype : inttype  ; var x : internal ;
  841. var y : cint64  ) ;
  842.  
  843.         (* Converts x into integer value of type i-type.  *)
  844.         
  845. var
  846. i, imax : integer ;
  847. s : strng ;
  848. carry : boolean ;
  849.  
  850. procedure i64nan ;
  851.         (* Creates an int64 nan *)
  852. var i : integer ;
  853. begin (* i64nan *)
  854. x.significand[0] := true ;
  855. for i := 1 to stickybit do x.significand[i] := false ;
  856. end   (* i64nan *) ;
  857.  
  858. begin
  859. case itype of
  860. i16 : imax := 16 ;
  861. i32 : imax := 32 ;
  862. i64 : imax := 64 ;
  863. otherwise
  864. end ;
  865.  
  866. case abs(kind(x)) of
  867. otherwise ;
  868. unnormkind, normkind : begin
  869. roundint( x, fpstatus.mode.round, xprec) ;
  870. donormalize(x) ;
  871. if kind(x) <> zerokind then begin
  872. if x.exponent < 64 then right( x, 64 - x.exponent ) ;
  873. if x.exponent > 64 then 
  874.         begin
  875.         left ( x, x.exponent - 64 ) ;
  876.         end ;
  877. if (x.exponent >= imax) and (* Exclude case of max negative integer.  *)
  878. ((x.exponent <> imax) or (not x.sign) or 
  879. (lastbit(x,leastsigbit-imax+1,leastsigbit) > (leastsigbit-imax+1)))
  880. then begin
  881. x.significand[leastsigbit+1-imax] := false ; (* Turn off bit to allow room
  882.         for sign bit.  *)
  883. setex ( cvtovfl ) ;
  884. end ;
  885. if (itype=i64) and (x.exponent >= imax) then
  886.         begin (* overflowed to nan *)
  887.         i64nan ;
  888.         setex(cvtovfl) ; (* Might not have been set for -2^63.  *)
  889.         end   (* overflowed to nan *) ;
  890. end 
  891. end
  892.  ;
  893.  
  894. infkind : begin
  895. setex ( cvtovfl  ) ;
  896. if itype = i64 then i64nan else
  897.         begin (* not i64 *)
  898.         for i := leastsigbit downto (leastsigbit - imax + 2 ) 
  899.         do x.significand[i] := true ;
  900.         x.significand[leastsigbit-imax+1] := false ;
  901.         end   (* not i64 *) ;
  902. end ;
  903. nankind : begin
  904. if itype = i64 then i64nan else
  905.         begin (* not i64 *)
  906.         setex ( invop ) ;
  907.         for i := leastsigbit downto (leastsigbit - imax + 2  ) 
  908.         do x.significand[i] := false ;
  909.         x.significand[leastsigbit-imax+1] := true ;
  910.         end   (* not i64 *) ;
  911. end ;
  912.  
  913. end ;
  914.  
  915. if x.sign then begin (* Complement.  *)
  916. carry := false ;
  917. for i := leastsigbit downto (leastsigbit - imax + 1) do
  918. suber( false, x.significand[i], x.significand[i], carry ) ;
  919. end ;
  920.  
  921. for i := 0 to 7 - (imax div 8) do y[i] := 0 ;
  922. for i := (8 - (imax div 8)) to 7 do
  923. y[i] := xbyte( x, leastsigbit - 63 + 8*i, leastsigbit - 56 + 8*i ) ;
  924.  
  925. write(' Integer format: ') ;
  926. for i := (8 - (imax div 8)) to 7 do  begin
  927. bytehex(y[i],s) ;
  928. write(s[1],s[2],' ') ;
  929. end ;
  930. writeln ;
  931.  
  932. unpackinteger( y, x, itype ) ;
  933.  
  934. end ;
  935.  
  936.  
  937. End-Of-File
  938. echo Extracting dotest.i
  939. cat >dotest.i <<'End-Of-File'
  940.  
  941. procedure dotest (* s : strng ; var found : boolean ; x, y : internal  *) ;
  942.  
  943. var
  944. ztrue, z, r : internal ;
  945. cc : conditioncode ;
  946. ps : pstack ;
  947. error : boolean ;
  948. i, k: integer ;
  949. yi : cint64 ;
  950. ms : fpmodetype ; es, ts : excepset ;
  951.  
  952. procedure subRR ;
  953.  
  954. begin
  955. if sequal(s , 'REM') then begin
  956. found := true ;
  957. trem( y, x,  z ) ;
  958. end 
  959. end ;
  960.  
  961. procedure subS ;
  962.  
  963. var
  964. xr,yr,zr :real ;
  965.  
  966. begin
  967. if sequal(s , 'SCALE') then begin
  968. found := true ;
  969.  
  970.  
  971. cscale( y, x,  z ) ;
  972.  
  973. end else if sequal(s , 'SQRT') then begin
  974. found := true ;
  975.  
  976. tsqrt( x, z) ;
  977.  
  978. end 
  979. end ;
  980.  
  981. procedure subT ;
  982.  
  983. var yi : cint64 ;
  984.  
  985. begin
  986. if sequal(s , 'TEST') then begin
  987. found := true ;
  988. pretest( storagemode )  ;
  989. end 
  990. else if sequal(s , 'TOF32') then begin (* Convert to single.  *)
  991. found := true ;
  992. tconvert(x,z,flt32) ;
  993. end else if sequal(s , 'TOF32I') then begin (* Convert to single integral.  *)
  994. found := true ;
  995. tintconvert(x,z,flt32) ;
  996. end else if sequal(s , 'TOF64') then begin (* Convert to double.  *)
  997. found := true ;
  998. tconvert(x,z,f64) ;
  999. end else if sequal(s , 'TOF64I') then begin (* Convert to double integral.  *)
  1000. found := true ;
  1001. tintconvert(x,z,f64) ;
  1002. end else  if sequal(s , 'TOX80') then begin (* Convert to extended.  *)
  1003. found := true ;
  1004. tconvert(x,z,ext80) ;
  1005. end else if sequal(s , 'TOX80I') then begin (* Convert to extended integral.  *)
  1006. found := true ;
  1007. tintconvert(x,z,ext80) ;
  1008. end else if sequal(s , 'TOI16') then begin (* Convert to 16 bit integer.  *)
  1009. found := true ;
  1010. tconvert(x,z,i16) ;
  1011. end else if sequal(s , 'TOI32') then begin (* Convert to 32 bit integer.  *)
  1012. found := true ;
  1013. tconvert(x,z,i32) ;
  1014. end else if sequal(s , 'TOI64') then begin (* Convert to 64 bit integer.  *)
  1015. found := true ;
  1016. tconvert(x,z,i64) ;
  1017. end  ;
  1018. end ;
  1019.  
  1020.  
  1021. begin
  1022. writeln(' BEGIN TEST ') ;
  1023. makezero(z) ; (* Define default "computed result" for those operations
  1024.         that don't return any.  *)
  1025. if stack = nil then makezero(ztrue) else ztrue := stack^.x ;
  1026. if not sequal(s,'TEST') then begin (* Not ready to do these mode switches until
  1027. initialization has been accomplished.  *)
  1028.  
  1029. ms := fpstatus.mode ;
  1030. swapmode(ms) ;
  1031. ts := fpstatus.trap ;
  1032. swaptrap(ts) ;
  1033. es := fpstatus.excep ;
  1034. swapexcep(es) ;
  1035. end ;
  1036. found := false ;
  1037. if length(s) > 0 then case s[1] of
  1038.  
  1039. '+' : if length(s)=1 then begin
  1040. found := true ;
  1041.  
  1042. tadd( y, x,  z ) ;
  1043.  
  1044. end ;
  1045.  
  1046. '-' : if length(s)=1 then begin
  1047. found := true ;
  1048.  
  1049. tsub( y, x,  z ) ;
  1050.  
  1051. end ;
  1052.  
  1053. '*' : if length(s)=1 then begin
  1054. found := true ;
  1055. tmul (y, x, z) ;
  1056.  
  1057. end ;
  1058.  
  1059. '/' : if length(s) = 1 then begin
  1060. found := true ;
  1061. tdiv ( y, x,  z) ;
  1062.  
  1063. end ;
  1064. 'A' : if sequal(s , 'ABS') then begin
  1065. found := true ;
  1066. tabs(x,z) ;
  1067. end
  1068.  ;
  1069.  
  1070. 'C' : if sequal(s , 'COMPARE') then begin
  1071. found := true ;
  1072. tcompare( y, x,  cc) ;
  1073. write(' Compare result: ') ;
  1074. case cc of
  1075. lesser : writeln(' < ') ;
  1076. equal : writeln(' = ' ) ;
  1077. greater : writeln(' > ') ;
  1078. notord : writeln(' Unordered ') ;
  1079. end ;
  1080. for i := 0 to 6 do yi[i] := 0 ;
  1081. yi[7] := ord(cc) ;
  1082. unpackinteger(yi, z, i16);
  1083. end ;
  1084.  
  1085. 'L' : if sequal(s , 'LOGB') then begin
  1086. found := true ;
  1087. clogb( x,  z ) ;
  1088. end ;
  1089.  
  1090. 'N' : if sequal(s , 'NEG') then begin (* NEGATE top of stack *)
  1091. found := true ;
  1092. tneg(x,z) ;
  1093. end 
  1094. else if sequal(s , 'NEXT') then begin (* Compute NEXTAFTER function.  *)
  1095. found := true ;
  1096. cnextafter( y, x,  z ) ;
  1097.  
  1098. end ;
  1099.  
  1100. 'R' : subRr ;
  1101. 'S' : subS ;
  1102. 'T' : subT ;
  1103.  
  1104. otherwise
  1105.  
  1106. end ;
  1107.  
  1108. if found then writeln( ' Did ',s) ;
  1109.  
  1110. if not found then begin (* check for decimal input *)
  1111. tdecbin(s, z, error ) ;
  1112. if not error then begin
  1113. found := true ;
  1114.  
  1115. end
  1116. end ;
  1117. if sequal(s,'TEST') then writeln(' Begin TEST Mode ')
  1118. else begin
  1119. if  found then begin
  1120. tstore(storagemode,z) ;
  1121. swapexcep(es) ;
  1122. if (es=fpstatus.excep) and (equalinternal(z,ztrue)) then
  1123. writeln(' OK! ') 
  1124. else 
  1125. begin
  1126. if es <> fpstatus.excep then
  1127.         begin
  1128.         write(chr(ordbell),' DIFFERENT FLAGS: ') ;
  1129.         displayexcep(es) ;
  1130.         writeln ;
  1131.         end ;
  1132. if not equalinternal( z, ztrue ) then
  1133.         begin
  1134.         writeln(chr(ordbell),' DIFFERENT RESULT: ') ;
  1135.         display(z) ;
  1136.         end ;
  1137. end ;
  1138. tdisplay(z) ;
  1139. writeln(' END TEST  ') ;
  1140. end
  1141. else  writeln(' Command not tested: ',s) ;
  1142. end ;
  1143. end ;
  1144.  
  1145.  
  1146.  
  1147. End-Of-File
  1148. echo Extracting hex.i
  1149. cat >hex.i <<'End-Of-File'
  1150. (* File hex.i, Version 8 October 1984 *)
  1151.  
  1152. procedure puthex ( s : strng ; p1, p2 : integer ; 
  1153.                 var x : internal ; var error : boolean ) ;
  1154.                 
  1155.                 (* Interprets s as a hex integer, puts value in bits
  1156.                 p1..p2 of x.significand.
  1157.                 Sets Error if any significant bits don't fit in field.  *)
  1158.  
  1159. var
  1160. i, j : integer ;
  1161. nib : nibarray ;
  1162.  
  1163. begin
  1164. error := false ;
  1165. for i := p1 to p2 do x.significand[i] := false ; (* Clear field.  *)
  1166. i := p2 + 1 - 4 * length(s) ;
  1167. while i < p2 do begin
  1168. hexnibble( s[1], nib ) ;
  1169. delete ( s, 1, 1 ) ;
  1170. for j := 0 to 3 do if nib[j] then begin
  1171. if (i+j) < p1 then error := true else x.significand[i+j] := true ;
  1172. end ;
  1173. i := i + 4 ;
  1174. end ;
  1175. end ;
  1176.  
  1177. procedure intdec ( i : integer ; var s : strng ) ;
  1178.         (* converts 16 bit integer to decimal strng *)
  1179. var
  1180. sign : boolean ;
  1181. t : strng ;
  1182.  
  1183. begin
  1184. if i = 0 then 
  1185.     begin
  1186.     s[0] := chr(1) ;
  1187.     s[1] := '0' ;
  1188.     end
  1189.     else begin
  1190. t[0] := chr(1) ;
  1191. s[0] := chr(0) ;
  1192. sign := false ;
  1193. if i < 0 then if i < -32767 then begin
  1194. makeucsdstring(' -32768',s) ; i := 0 end
  1195. else begin
  1196. sign := true ; i := -i end ;
  1197. while i <> 0 do begin
  1198. t[1] := chr( ord('0') + i mod 10 ) ;
  1199. s := concat ( t, s ) ;
  1200. i := i div 10 ;
  1201. end ; 
  1202. if sign then 
  1203.     begin
  1204.     t[1] := '-' ;
  1205.     s := concat( t, s ) ;
  1206.     end ;
  1207. end
  1208. end ;
  1209.  
  1210. procedure subhex ( x : internal ; p1, p2 : integer ; var s: strng ) ;
  1211.         (* s receives a strng of hex digits representing the integer in
  1212.         x.significand[p1]..x.significand[p2], right justified.  *)
  1213. var
  1214. j, i : integer ;
  1215. nib : nibarray ;
  1216.  
  1217. begin
  1218. i := p1 ;
  1219. while ( i < p2 ) and not x.significand[i] do i := i + 1 ;
  1220.         (* Find most significant non-zero bit in field.  *)
  1221. if ( i >= p2 ) and not x.significand[p2] then 
  1222.     begin
  1223.     s[0] := chr(1) ;
  1224.     s[1] := '0' ;
  1225.     end
  1226.     else begin
  1227. s[0] := chr(0) ;
  1228. i := p2 - 3 - 4 * (( p2 - i ) div 4 ) ;
  1229.         (* Start at left end of nibarray containing most significant bit.  *)
  1230. while i < p2 do begin
  1231. for j := 0 to 3 do 
  1232. if (i+j) < p1 then nib[j] := false else nib[j] := x.significand[i+j] ;
  1233. concatchar( s, nibblehex(nib)) ;
  1234. i := i + 4 ;
  1235. end ;
  1236. end ;
  1237. end ;
  1238.  
  1239. procedure tohexint ( x : internal ; var s : strng ) ;
  1240.  
  1241. (* if x is an integer less than 2**16,
  1242. then s receives the hex digits representing x.
  1243. Otherwise s is set to empty. *)
  1244.  
  1245. var
  1246. i, npoint : integer ;
  1247. nib : nibarray ;
  1248. integral : boolean ;
  1249. t : strng ;
  1250.  
  1251. begin
  1252. s[0] := chr(0) ;
  1253. if kind(x) = zerokind then 
  1254.     begin
  1255.     s[0] := chr(1) ; s[1] := '0' ;
  1256.     end
  1257.     else
  1258. if (abs(kind(x)) = normkind) and (x.exponent <= 16) and (x.exponent >= 1)
  1259. then begin
  1260. if zerofield ( x, x.exponent, stickybit ) then begin (* it's all integer *)
  1261. subhex ( x, 0, x.exponent - 1, s ) ;
  1262. if x.sign then 
  1263.     begin
  1264.     t[0] := chr(1) ;
  1265.     t[1] := '-' ;
  1266.     s := concat( t, s ) ;
  1267.     end ;
  1268. end end
  1269. end ;
  1270.  
  1271. procedure nanascii ( x : internal ; ishex : boolean ; var s : strng ) ;
  1272.  
  1273.         (* Converts an INF or NAN into strng s, using hex for numeric
  1274.         field values if ishex is true, and decimal if ishex is false.  *)
  1275.         
  1276. var t,t1 : strng ;
  1277. k : integer ;
  1278.  
  1279. begin
  1280. case kind(x) of
  1281. neginf : makeucsdstring('--',s) ;
  1282. infkind : makeucsdstring('++',s) ;
  1283. negnan, nankind : begin
  1284. makeucsdstring('NaN''',s) ;
  1285. if x.sign then 
  1286.     begin
  1287.     t[1] := '-' ;
  1288.     s := concat( t, s ) ;
  1289.     end ;
  1290. if ishex then 
  1291.         begin (* ishex nan *)
  1292.         subhex ( x, 1, 15, t ) ;
  1293.         if not zerofield(x,16,leastsigbit) then
  1294.                 begin (* Extra stuff *)
  1295.                 concatchar(t,':') ; (* Colon delimits extra stuff.  *)
  1296.                 for k := 4 to 15 do
  1297.                         begin (* Add hexit.  *)
  1298.                         subhex(x,4*k,4*k+3,t1) ;
  1299.                         t := concat(t,t1) ;
  1300.                         end   (* Add hexit.  *) ;
  1301.                 while t[length(t)] = '0' do
  1302.                         delete (t,length(t),1) ; (* Clear trailing zeros. *)
  1303.                 end   (* Extra stuff *) ;
  1304.         end   (* ishex nan *)
  1305. else
  1306.         if zerofield( x, 1, 15 ) then makeucsdstring('0.',t) else
  1307.                 begin (* Decimal Nan, non zero *)
  1308.                 subdec ( x, 1, 15, t ) ;
  1309.                 concatchar(t,'.') ; (* . Distinguishes decimal NAN from hex *)
  1310.                 end   (* Decimal Nan, non zero *) ;
  1311. s := concat ( s, t) ;
  1312. concatchar(s, '''') ;
  1313. end ;
  1314. otherwise
  1315. end ;
  1316. end ;
  1317.  
  1318. procedure binhex (* x : internal ; var s  : strng *)(* forward *)  ;
  1319. (* converts x to hex format *)
  1320.  
  1321. var
  1322. i, j, k : integer ;
  1323. nib : nibarray ;
  1324. t : strng ;
  1325.  
  1326. begin
  1327. case abs(kind(x)) of
  1328. zerokind : if x.sign then 
  1329.     begin
  1330.     s[0] := chr(1) ; s[1] := '0' ;
  1331.     end 
  1332.     else 
  1333.     begin
  1334.     s[0] := chr(2) ; s[1] := '-' ; s[2] := '0' ;
  1335.     end ;
  1336.  
  1337. unnormkind, normkind : begin
  1338. tohexint(x, s) ;
  1339. if length(s) > 0 then 
  1340.     begin
  1341.     makeucsdstring('H ',t) ; s := concat(s, t) ;
  1342.     end
  1343.     else 
  1344.     begin
  1345. s[0] := chr(1) ;
  1346. s[1] := '.' ;
  1347. for i := 0 to 3 do begin
  1348. for j := 0 to 3 do begin
  1349. for k := 0 to 3 do
  1350. nib[k] := x.significand[k+4*j+16*i] ;
  1351. concatchar(s, nibblehex(nib)) ;
  1352. end ;
  1353. concatchar( s, ' ' ) ;
  1354. end ;
  1355. nib[0] := x.significand[64] ;
  1356. nib[1] := x.significand[65] or x.significand[66] ;
  1357. nib[2] := false ;
  1358. nib[3] := false ;
  1359. concatchar(s, nibblehex(nib)) ;
  1360.  
  1361. while( (s[length(s)] = ' ') or( s[length(s)] = '0')) and
  1362. (length(s) > 2) do delete(s,length(s),1) ; (* delete trailing 0 and blank *)
  1363. makeucsdstring('H ',t) ;
  1364. s := concat(s,t) ; 
  1365. if x.exponent <> 0 then begin
  1366. if x.exponent > 0 then concatchar(s, '+') ;
  1367. intdec(x.exponent, t) ;
  1368. s := concat(s,t) ;
  1369. end ;
  1370. if x.sign then 
  1371.     begin
  1372.     makeucsdstring('- ',t) ;
  1373.     s := concat(t,s) ;
  1374.     end ;
  1375. end end ;
  1376.  
  1377. infkind, nankind : nanascii ( x, true, s ) ;
  1378.  
  1379. otherwise
  1380. end ;
  1381. end ;
  1382.  
  1383. procedure NANer ( s : strng ; ishex : boolean ;
  1384.         var x : internal ; var error : boolean ) ;
  1385.         (* Checks for strng in proper INF or NAN format.
  1386.         If ishex is true, interprets numeric constants in hex;
  1387.         If ishex is false, interprets them in decimal.  *)
  1388. var
  1389. i, k : integer ;
  1390. t, snan : strng ;
  1391. nminus, ndot, nplus : integer ;
  1392. dset : set of char ;
  1393. err : boolean ;
  1394.  
  1395. procedure bump ; (* removes first character from strng t *)
  1396. begin
  1397. delete (t,1,1) 
  1398. end ;
  1399.  
  1400. begin
  1401. error := false ;
  1402. t[0] := chr(0) ;
  1403. for i := 1 to length(s) do if s[i] <> ' ' then concatchar(t,upcase(s[i])) ;
  1404. concatchar(t,'z') ;
  1405.  
  1406. nminus := 0 ;  nplus := 0 ;  
  1407. for i := 1 to length(t) do case t[i] of
  1408. '-' : nminus := nminus + 1 ;
  1409. '+' : nplus := nplus + 1 ;
  1410. otherwise 
  1411. end ;
  1412. if (nplus >= 2) and (nplus>=( length(t)-1)) then begin (* plus infinity *)
  1413. x.exponent := maxexp ;
  1414. makeucsdstring('z ',t) ;
  1415. end ;
  1416. if (nminus >= 2) and (nminus=( length(t)-1) ) then begin (* minus inf *)
  1417. x.exponent := maxexp ;
  1418. makeucsdstring('-z',t) ;
  1419. end ;
  1420. x.sign := t[1]='-' ; (* Check sign *)
  1421. if x.sign then bump else if t[1]='+' then bump ;
  1422. if (length(t) >= 3) 
  1423.  then (* check for NAN *)
  1424. if (t[1]='N') and (t[2]='A') and (t[3]='N')  then 
  1425.         begin (* Nan processing *)
  1426.         bump ; bump ; bump ;
  1427.         x.exponent := maxexp ;
  1428.         if t[1]='''' then 
  1429.                 begin (* Process significand string *)
  1430.                 bump ; (* Remove ' *)
  1431.                 if ishex then dset := hexset else dset := digitset ;
  1432.                 snan[0] := chr(0) ;
  1433.                 while t[1] = '0' do bump ;
  1434.                 while t[1] in dset do begin (* Accumulate field value. *)
  1435.                 concatchar( snan, t[1] ) ;
  1436.                 bump ;
  1437.                 end ;
  1438.                 if ishex then 
  1439.                 puthex( snan, 1, 15, x, error ) 
  1440.                 else
  1441.                 putdec( snan, 1, 15, x, error ) ;
  1442.                 if ishex then 
  1443.                         begin (* Extra Hex Processing.  *)
  1444.                         if t[1] = ':' then
  1445.                                 begin (* Extra hex stuff *)
  1446.                                 bump ;
  1447.                                 k := 16 ;
  1448.                                 snan[0] := chr(1) ;
  1449.                                 snan[1] := ' ' ;
  1450.                                 while (k <= (leastsigbit-3)) and 
  1451.                                                 (t[1] in dset) do
  1452.                                         begin
  1453.                                         snan[1] := t[1] ;
  1454.                                         puthex(snan,k,k+3,x,err) ;
  1455.                                         k := k + 4 ;
  1456.                                         bump ;
  1457.                                         end ;
  1458.                                 end   (* Extra hex stuff *) ;
  1459.                         if t[1]='''' then bump ; (* Absorb final delimiter.  *)
  1460.                         end   (* Extra Hex Processing.  *) 
  1461.                 else
  1462.                         begin (* Extra Dec Processing *)
  1463.                         if t[1]='.' then 
  1464.                                 begin (* Decimal Point Found *)
  1465.                                 bump ; (* Absorb decimal point.  *)
  1466.                                 if t[1]='''' then bump ; 
  1467.                                         (* Absorb final delimiter.  *)
  1468.                                 end   (* Decimal Point Found *) ;
  1469.                         end   (* Extra Dec Processing *) ;
  1470.                 if length(t) > 1 then
  1471.                         begin (* Extra characters *)
  1472.                         error := true ;
  1473.                         while (length(t)>1) and (t[1]<>'''') do bump ;
  1474.                         if t[1]='''' then bump ;
  1475.                         end   (* Extra characters *) ;
  1476.                 end   (* Process significand string *) ;
  1477.         
  1478.         if error or zerofield( x, 1, leastsigbit ) then
  1479.                 begin
  1480.                 error := false ;
  1481.                 makenan(nanascnan,x) ;
  1482.                 (* NAN  format without significand is invalid. *)
  1483.                 end ;
  1484.         end   (* Nan Processing *);
  1485. if length(t) > 1 then 
  1486.         begin
  1487.         error := true ;
  1488.         end ;
  1489. end  (* NANer *) ;
  1490.  
  1491. procedure hexbin (* s : strng ; var x : internal ; var error : boolean *) ;
  1492. (* converts hex strng s to internal format *)
  1493. (* error is set true if bad format *)
  1494.  
  1495. type
  1496. stringclass = (nonnumeric, truezero, nonzero) ; (* types of strng *)
  1497.  
  1498. var
  1499. class : stringclass ;
  1500. i, k,  min : integer ;
  1501. sigpoint : integer ;
  1502. t, snan : strng ;
  1503. esign : boolean ;
  1504. nib : nibarray ;
  1505. ee : integer ;
  1506.  
  1507. procedure bump ; (* removes first character from strng t *)
  1508. begin
  1509. delete (t,1,1) 
  1510. end ;
  1511.  
  1512.  
  1513. begin
  1514. class := nonnumeric ;
  1515. error := false ;
  1516. esign := false ;
  1517. x.sign := false ;
  1518. x.exponent := 0 ;
  1519. ee := 0 ;
  1520. for i := 0 to stickybit do x.significand[i] := false ;
  1521. sigpoint := 0 ;
  1522. t[0] := chr(0) ;
  1523. for i := 1 to length(s) do if s[i] <> ' ' then concatchar(t,upcase(s[i])) ;
  1524. concatchar(t,'!') ; (* this marks the end of the input strng *)
  1525.  
  1526. if t[1] = '+' then bump else if t[1] = '-' then begin (* handle negative *)
  1527. x.sign := true ;
  1528. bump
  1529. end ;
  1530. while t[1] = '0' do begin
  1531. class := truezero ;
  1532. bump ; (* delete leading zeros *)
  1533. end ;
  1534. while t[1] in hexset do begin (* digits before point *)
  1535. class := nonzero ;
  1536. hexnibble(t[1], nib) ;
  1537. if sigpoint <= (stickybit-4) then min := 3 else min := (stickybit-1)-sigpoint ;
  1538. for i := 0 to min do x.significand[sigpoint+i] := nib[i] ;
  1539. for i := (stickybit-sigpoint) to 3 do x.significand[stickybit] := x.significand[stickybit] or nib[i] ;
  1540. x.exponent := x.exponent + 4 ;
  1541. if x.significand[0] then begin
  1542. if sigpoint <= (stickybit-4) then sigpoint := sigpoint + 4 else sigpoint := stickybit
  1543. end else begin (* donormalize *)
  1544. donormalize(x) ;
  1545. sigpoint := x.exponent ;
  1546. end ;
  1547. bump
  1548. end ;
  1549. if t[1] = '.' then begin (* check for point *)
  1550. bump ;
  1551. while t[1] in hexset do begin (* process digits after point *)
  1552. if (t[1] <> '0') or (class = nonzero) then class := nonzero 
  1553. else class := truezero ;
  1554. hexnibble(t[1], nib) ;
  1555. if sigpoint <= (stickybit-4) then min := 3 else min := (stickybit-1)-sigpoint ;
  1556. for i := 0 to min do x.significand[sigpoint+i] := nib[i] ;
  1557. for i := (stickybit-sigpoint) to 3 do 
  1558. x.significand[stickybit] := x.significand[stickybit] or nib[i] ;
  1559. if x.significand[0] then begin
  1560. if sigpoint <= (stickybit-4) then sigpoint := sigpoint + 4 else 
  1561. sigpoint := stickybit
  1562. end else if t[1] = '0' then x.exponent := x.exponent - 4 else  
  1563. begin (* donormalize *)
  1564. sigpoint := x.exponent ;
  1565. donormalize(x) ;
  1566. sigpoint := 4 + x.exponent - sigpoint ;
  1567. end ;
  1568. bump ; 
  1569. end ;  
  1570. end ;
  1571. if t[1] = 'H' then bump ; (* handle H for Hex *)
  1572. if t[1] = '+' then bump else if t[1]='-' then begin (* exponent sign *)
  1573. esign := true ;
  1574. bump
  1575. end ;
  1576. while t[1] in digitset do begin (* exponent digits *)
  1577. if ee > ((maxexp - (ord(t[1])-ord('0'))) div 10 ) then begin
  1578. error := true ;
  1579. ee := maxexp - 1 ;
  1580. end else
  1581. begin
  1582. ee := 10 * ee + ord(t[1]) - ord('0') ;
  1583. end ; bump  end ;
  1584. if class = truezero then x.exponent := minexp  else begin
  1585. if esign then ee := -ee ;
  1586. if (x.exponent >= 0 ) and (ee > 0 ) then if x.exponent >= (maxexp - ee)
  1587. then begin
  1588. error := true ;
  1589. x.exponent := maxexp - 1 ;
  1590. end ;
  1591. if (x.exponent < 0) and ( ee < 0 ) then if x.exponent <= (minexp - ee) 
  1592. then begin
  1593. error := true ;
  1594. x.exponent := minexp + 1 ;
  1595. end ;
  1596. if not error then x.exponent := x.exponent + ee ;
  1597. end ;
  1598. if class = nonnumeric  then 
  1599.         (* the following code checks for INFs and NANs *)
  1600. NANer ( s, true, x, error ) 
  1601. else
  1602. if ( length(t) > 1) then error := true  ;
  1603. if error then 
  1604.         begin (* Erroneous input *)
  1605.         makenan(nanascbin,x) ;
  1606.         end
  1607. end ;
  1608.  
  1609.  
  1610.  
  1611. End-Of-File
  1612. echo ""
  1613. echo "End of Kit"
  1614. exit
  1615.  
  1616.