%!PS % An 8 Decimal Point PostScript Real Reporter Utility % ==================================================== % by Don Lancaster PS8DPRPT.PSL % Copyright c 2007 by Don Lancaster & Synergetics, Box 809, Thatcher, AZ, 85552 % (928) 428-4073 Email: don@tinaja.com Website: http://www.tinaja.com % Consulting services available http://www.tinaja.com/info01.html % Linking welcome. Reposting expressly forbidden. % All commercial rights and all electronic media rights ~fully~ reserved. % Linking usually welcome. Reposting expressly forbidden. Version 1.1 % PostScript reals are internally calculated to near 8 decimal point precision % by use of their IEEE 32 bit floating point routines. The real results are % normally only reported to six decimal points. While more than adequate for % the majority of PS users, certain PostScript-as-Language apps may demand % (or at least welcome) more reportable precision. % The utilities presented here provide reporting of up to eight decimal % point precision. There typically will be a count or two of innacuracy % on the eighth decimal point. The reporting accuracy improvement will % approach 100:1. No internal mods to the PostScript interpreter are made. % IMPORTANT NOTE: Don Lancaster's file gonzo.ps is optional for this utility % but recommended for its use. % After obvious location mods, uncomment ONE of the following two lines: % (C:\\Documents and Settings\\don\\Desktop\\gonzo\\gonzo.ps) run % use internal gonzo % (A:\\gonzo.ps) run % use external gonzo % NOTE THAT ALL PS FILENAME STRINGS !!!DEMAND!!! DOUBLE REVERSE SLASHES. %%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%% % PostScript normally reports real values only to six decimal point precision. % Internally, nearly eight decimal points of precision are available per the % IEEE floating point routines. Certain custom PostScript-as-language apps may % demand ( or at least welcome ) more than six decimal points of precision. % /realto8dstring converts any signed PostScript real in the absolute range % of 0.000000001 to 999,999,999 to a reportable string accurate to nearly eight % decimal points of precision. Larger absolute values create an error while % smaller ones truncate and report as 0.0000000 or -0.0000000. % To use, place a real number or its variable on the stack and call % realto8dstring. The equvalent reportable string returns to the stack top. % Operation is based on converting any real over the allowable range to % an integer in the 10 to 100 million range, converting that integer to % a string, and modifying the string as needed for a decimal point and sign. % This utility presently operates over an absolute value range of 0.0000001 % to 99,999,999. Larger values are reported as errors. Smaller values are % truncated to 0.00000000. % One count or more uncertainties may exist in the eighth decimal place. % /mergestr is a string merger from my gonzo utilities. Complete utilities % are found at http://www.tinaja.com/post01.asp#gonzo ... /mergestr {2 copy length exch length add string dup dup 4 3 roll 4 index length exch putinterval 3 1 roll exch 0 exch putinterval} def % /realto8dstring is the high level code for the reporting conversion. It % determines the sign and then tests for values too large or too small. % It then goes to processgoodreal for actual report conversions. % A final deferencing is done to provide a unique output string. /realto8dstring {dup 0 lt % test and flag negatives /isneg exch store abs /val exch store % save real as absolute value val 100000000 ge { % report and error trap values (real is too big! )== % that are too large to process real_is_too_big! } if val 0.00000001 le % truncate small numbers to zero {(0.0000000)} {processgoodreal} ifelse % process numbers versus zeros isneg {(-)}{( )} ifelse % create leading space or minus exch mergestr % add leading space or minus 20 string cvs % dereference string to avoid % any possible rude surprises } store % /processgoodreal continues the realto8string processing after numbers too % large and too small have been dealt with. Subprocs are called for tenmillions, % unitsormore, and fractions. Note that log floor cvi tells you the decade % size and position of any positive number. /processgoodreal { val log floor cvi % evaluate decimal location /posn exch store % posn 7 eq {tenmillions} % treat ten millions special {posn 0 ge {unitsormore} % handle >1 as a class {fractions} % handle fractions as a class ifelse } ifelse } store % /tenmillions handles ten millions as a special case needing no reformatting. /tenmillions { val round cvi % use ten millions val as is. 20 string cvs } store % /unitsormore handles units through millions... /unitsormore { /workstring val % scale val as needed to 10-99 megs 1 7 posn sub {10 mul} % this may give more accuracy repeat mul round cvi 20 string cvs store % and convert to string workstring 0 posn 1 add % stuff decimal point getinterval (.) mergestr workstring % post remainder of string posn 1 add workstring length 1 sub posn sub getinterval mergestr 20 string cvs % dereference } store % /fractions handles fractional values /fractions {/workstring val % scale workstring 1 7 posn sub {10 mul} repeat % this may give more accuracy mul round cvi 20 string cvs store % and convert to string (0.) % prepend leading zero and dp posn neg 1 sub % add intermediate zeros {(0) mergestr} repeat workstring mergestr % postpend value 20 string cvs % dereference } store %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%% demo - remove or alter before reuse %%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % An "Empty job. No PDF file produced." message is normal and expected. 2 sqrt 10000000 mul realto8dstring == 2 sqrt 1000000 mul neg realto8dstring == % negs may be placed anywhere. 2 sqrt 100000 mul realto8dstring == 2 sqrt 10000 mul neg realto8dstring == 2 sqrt 1000 mul realto8dstring == 2 sqrt 100 mul neg realto8dstring == 2 sqrt 10 mul realto8dstring == 2 sqrt neg realto8dstring == 2 sqrt 0.1 mul realto8dstring == 2 sqrt 0.01 mul realto8dstring == 2 sqrt 0.001 mul realto8dstring == 2 sqrt 0.0001 mul realto8dstring == 2 sqrt 0.00001 mul realto8dstring == 2 sqrt 0.000001 mul realto8dstring == 2 sqrt 0.0000001 mul realto8dstring == 2 sqrt 0.00000001 mul realto8dstring == 2 sqrt 0.000000001 mul realto8dstring == (real zero follows) 0 realto8dstring == % uncomment to test large value error trapping % 2 sqrt 1000000000 mul realto8dstring == % EOF