Morgan - Numerical Methods (523161), страница 31
Текст из файла (страница 31)
This allows the conversion of longs and ints as well as purely fractionalvalues; the number to be converted need only be aligned within the fixed-point field.The extended-precision format these routines use requires three words for thesignificand, exponent, and sign; therefore, if we shift the fixed-point number so thatits topmost one is in bit 7 of the fourth byte, we’re almost there. We simply need tocount the shifts, adding in an appropriate offset and sign.
Here’s the procedure.ftf: Algorithm1.The fixed-point value (binary) is on the stack along with a pointer (rptr)to the float to be created. Flags for the exponent (exponent) and sign(nmsin) are cleared.2.Check the fixed-point number for sign. If it's negative, two'scomplement it.3.Scan the fixed-point number to find out which byte contains the mostsignificant nonzero bit.If the number is all zeros, return the appropriate float at step 9.If the byte found is greater than the fourth, continue with step 5.If the byte is the fourth, continue with step 6.If the byte is less than the fourth, continue with step 4.4.The most significant non zero bit is in the first, second, or third byte.Subtract our current position within the number from four to find outhow many bytes away from the fourth we are.Multiply this number by eight to get the number of bits in the shift andput this value in the exponent.Move as many bytes as are available up to the fourth position, zeroingthose lower values that have been moved and not replaced.Continue with step 6.5.The most significant nonzero bit is located in a byte position greaterthan four.Subtract four from our current position within the number to find howmany bytes away from the fourth we are.Multiply this number by eight to get the number of bits in the shift andput this value in the exponent.Move these bytes back so that the most significant nonzero byte is inthe fourth position.207NUMERICALMETHODSContinue with step 6.6.Test the byte in the fourth position to see whether bit 7 contains a one.If so, continue with step 7.If not, shift the first three words left one bit and decrement theexponent; continue at the start of step 6.7.Clear bit 7 of the byte in the fourth position (this is the hidden bit).Add 86H to exponent to get the correct offset for the number; place thisin byte 5.Test numsin to see whether the number is positive or negative.If it's positive, shift a zero into bit 7 of byte 5 and continue withstep 8.If it's negative, shift a one into bit 7 of byte 5 and continue withstep 8.8.Place bytes 4 and 5 in the floating-point variable, round it, and exit.9.Write zeros to every word and exit.ftf; Listing; *****;;unsigned conversion from quadword fixed point to short real;The intention is to accommodate long and int conversions as well.;Binary is passed on the stack and rptr is a pointer to the result.ftfproc uses si di, binary:qword, rptr:word;one word for near;pointerlocal exponent:byte, numsin:bytepushfxorax, axmovaddleamovdi,di,si,bx,do_numbers:mov208word ptr rptr6byte ptr binary[0]7byte ptr [exponent], al;point at future float;point to quadword;index;clear flagsINPUT, OUTPUT, AND CONVERSIONmovmovbyte ptr nurnsin, aldx, axmovorjnsnotnotnotnotnegjcaddadcadcal, byte ptr [si] [bx]al, alfind topbyte ptr numsinword ptr binary[6]word ptr binary[4]word ptr binary[2]word ptr binary[0]find_topword ptr binary[2], 1word ptr binary[4], 0word ptr binary[6], 0do_num:find_top:cmpjemovorjnedecjwfound_it:movcmpjajeshift_leftstdmovsubshlshlshlnegmovlealeabl, dlmake zeroal, byte ptr [si][bx]al,alfound itbxshort find_topdl, 80hbl, 4shift rightfinal right;record sign;this one is negative;compare index with 0;we traversed the entire;number;get next byte;anything there?;move index;test for MSB;radix point;above;equal;or below?cx, 4cx, bxcx, 1cx, 1cx, 1cxbyte ptr [exponent], cl;points to MSB;target;times 8;calculate exponentdi, byte ptr binary[4]si, byte ptr binary209NUMERICAL METHODSreprepaddmovincmovsbsi, bxcx, bxcxmovsubsubstosbjmpcx, 4cx, bxax, axshift_right:cldmovsubleamovsubreprep;move number for nomalization;clear unused bytesshort final_rightcx,cx,si,di,di,bx4byte ptr binary[4]sicxshlshlshlmovcl, 1cl, 1cl, 1byte ptr [exponent], clmovsubincmovsbsubmovsubsubleastosbcx, bxcx, 4cxbx,cx,cx,ax,di,;times 8;calculate exponent44bxaxword ptr binary;clear bytesfinal_right:leasi, byte ptr binary[4]final_rightl:movtestjnedecal, byte ptr [si]al, dlalignedbyte ptr exponent210;points to MSB;target;get most significant one into;MSB;are we there yet?INPUT,shlrclrcljmpaligned:shlmovaddcmpjestcjmppositive:clcget_ready_to_go:rcrmovOUTPUT,ANDCONVERSIONword ptr binary[0], 1word ptr binary[2], 1word ptr binary[41, 1short final_right1al, 1ah, 86h;clear bit;offset so that exponent will be;right after additionah, byte ptr exponentnumsin, dhpositiveshort get_ready_to_goax, 1;shift carry into MSB;put it all back the way it;should beword ptr binary[4], axftf_ex:invoke round, binary, rptr;round the floatexit:popfret;make_zero:stdsubmovstoswrepjmpendpftf;nothing but zerosax, axcx, 4;zero it all outshort exitSingle-Precision Floating Point to Fixed PointFtfx simply extracts the fixed-point number from the IEEE 754 floating-point211NUMERICAL METHODSformat and places it, if possible, in a fixed-point field composed of a 32-bit integerand a 32-bit fraction.
The only problem is that the exponent might put the significandoutside our fixed-point field. Of course, the field can always be changed; for thisroutine, it’s the quadword format with the radix point between the doublewords.fttx Algorithm1.Clear the sign flag, sinptr, and the fixed-point field it points to.2.Round the incoming floating-point number.3.Set the sign flag through sinptr by testing the MSB of the float.4.Extract the exponent and subtract the bias.
Restore the hidden bit.5.Test the exponent to see whether it's positive or negative.If it's negative, two's complement the exponent and test the range tosee if it's within 28H.If it's greater, go to step 9.If it's not greater, continue with step 7.If positive, test the range to see if it's within 18H.If it's less, go to step 10.If not, continue with step 6.6.Shift the integer into position and go to step 8.7.Shift the fraction into position and continue with step 8.8.See if the sign flag is set.If not, exit with success.If it is, two's-complement the fixed-point number and exit.9.Error. Write zeros to all words and exit.10. Write a 0ffH to the exponent and exit.fftx: Listing;*****; conversion of floating point to fixed point; Float enters as quadword.; Pointer, sptr, points to result.; This could use an external routine as well.
When the float; enters here, it is in extended format.212INPUT, OUTPUT, AND CONVERSIONftfxproc uses bx cx dx si di, fp:qword, sptr:wordlocalsinptr:byte, exponent:bytepushfstd;xormovmovmovax,axbyte ptr [sinptr],albyte ptr [exponent],aldi,word ptr sptr;point to resultround, fp, addr fp;fixup for translationax,word ptr fp[0]bx,word ptr fp[2]dx,word ptr fp[41dx,dxget_exponentbyte ptr [sinptr];get float;clear the sign;;***;do_rnd:invoke;set_sign:movmovmovorjnsnot;get_exponent:subshlsubmovmovandstcrcr;which_way:orjnsnegshift_right:cmpjamake_fractioncx,cxdx,1dh,86hbyte ptr exponent, dhcl,dhdx,0ffh;test exponent for sign;it is negative;dump sign;remove bias from exponent;store exponent;save number portiondl,l;restore hidden bitcl,clshift_leftcl;test for sign of exponentcl,28hmake_zero;range of fixed-point number;no significance too small;two's complement if negative213NUMERICAL METHODSshrdx,1rcrrcrloopmovmovmovimpbx,1ax,1make fractionword ptr [di] [0],axword ptr [di] [2],bxword ptr [di][4],dxshort print_result;shift fraction into position in;point variablefixedshift_left:cmPjamake_integershrrcrrcrloopmovmovmovprint_resulttestienotnotnotnegicaddadcadccl,18h;range of fixed point;(with significand);failed significance too bigmake_maxbx,1dx,1ax,1make_integerword ptr [di][6],axword ptr [di][4],dxword ptr [di][2],bxbyteexitwordwordwordwordexitwordwordword;and write result;shift into position;write outptr [sinptr], 0ffh;check for proper signptrptrptrptr;two's complement[di] [6][di][4][di] [2][di] [0]ptr [di] [2],1ptr [di] [4],0ptr [di] [6],0exit:popfret;make_zero:submovstoswrepimp;214;error make zeroax,axcx,4short exitINPUT, OUTPUT, AND CONVERSIONmake_max:submovstoswrepnotstoswandnotstoswjmpftfx;error too bigax,axcx,2axword ptr [di][4], 7f80hax;infiniteshort exitendp215NUMERICAL METHODS1Knuth, D.