Date: Wed, 17 Apr 1996 21:01:49 GMT Michael Friendly "SAS(r) Discussion" Michael Friendly York University, Ontario, Canada Finding the number of decimals in an IML matrix

Here's a problem that seems to point to either a flaw in my thinking or a bug in SAS/IML.

I'm working on a general routine to print multidimensional arrays, and need to determine the field width and number of decimal places. I'm using the mod function in a loop to find the first decimal place where all remainders are zero.

t = mod(abs(table),1); do dec = 1 to maxdec until( max(t)<.001 ); t = mod((10##dec)#abs(table),1); minmax = max(t) || sum(t > .1); print dec (10##-dec) minmax; print 'remainders', t; end;

For a 2-decimal table like this, the loop should stop after two iterations, but it doesn't (always). mod(number,1) or number - int(number) should always return a fraction less than 1, but don't seem to. WHY???

Here's some output. I'll include a complete program (just for this part) at the end, in case someone wants to play with it

TABLE 945.81 986.63 460.59 730.36 238.34 363.17 943.16 586.99 503.8 943.19 929.82 480.89 652.31 611.29 418.31 709.56 447.54 288.22 621.26 723.58 45.29 414.13 979.55 294.81 827.86 943.32 769.95 843.95 555.65 657.07 218.15 493.81 83.17 12.07 644.11 919.06 292.31 741.31 78.2 600.97 546.04 724.1 235.78 509.51 729.45 581.7 907.33 743 506.36 498.34 482.92 495.21 61.48 866.29 528.4 184.35 293.06 577.02 660.7 139.05 429.51 499.19 772.71 962.78 179.67 516.67 383.19 34.99 347.64 78.56 71.36 431.71

DEC #TEM1002 MINMAX 1 0.1 0.9 58

remainders

T 0.1 0.3 0.9 0.6 0.4 0.7 0.6 0.9 0 0.9 0.2 0.9 0.1 0.9 0.1 0.6 0.4 0.2 0.6 0.8 0.9 0.3 0.5 0.1 0.6 0.2 0.5 0.5 0.5 0.7 0.5 0.1 0.7 0.7 0.1 0.6 0.1 0.1 0 0.7 0.4 0 0.8 0.1 0.5 0 0.3 0 0.6 0.4 0.2 0.1 0.8 0.9 0 0.5 0.6 0.2 0 0.5 0.1 0.9 0.1 0.8 0.7 0.7 0.9 0.9 0.4 0.6 0.6 0.1

[so far, so good] DEC #TEM1002 MINMAX 2 0.01 1 2

remainders

T 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 36E-13 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 73E-13 0 0 0 0 0 0 0 0 0 0 0 0 0 18E-13 0 0 0 0 0 1 0 0 0 0 0 0 [why these 1's??]

DEC #TEM1002 MINMAX 3 0.001 1 1

remainders

T 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0

[next iteration deleted] FW DEC Field width, decimals 9 4

-- Here's the program --- proc iml;

start mdprint(dim, table, vnames, lnames) global (ls, maxdec);

if type(ls) = 'U' then ls=80; *-- output linesize; if type(maxdec) = 'U' then maxdec = 4; *-- maximum decimal places; nf = max( nrow(dim), ncol(dim) ); dw = 60; *-- display width; debug=0;

*-- determine field width, format; fw = 8; fw = 2 + floor( log10( max(abs(table)) ) ) + any( table<0 ); if all( mod(table,1) < .0001 ) then do; dec = 0; end; else do; t = mod(abs(table),1); do dec = 1 to maxdec until( max(t)<.001 ); t = mod((10##dec)#abs(table),1); *-- tried this way too; * t = ((10##dec)#abs(table)) - int((10##dec)#abs(table)); minmax = max(t) || sum(t > .1); print dec (10##-dec) minmax; print 'remainders', t; end; dec = dec-1; fw = fw + dec + 1; end; print 'Field width, decimals' fw dec; ** enough for now ; finish;

reset fw=6; dim = {8 3 3}; table = 1000 * uniform( j(dim[#], 1, 284241 )); table = shape(table,8, 9); table = round(table,.01); print table;

vnames ={'Var A' 'Var B' 'Var C'}; lnames ={ A1 A2 A3 A4 A5, B1 B2 B3 '' '', C1 C2 C3 '' ''}; run mdprint(dim, table, vnames, lnames);

-- Michael Friendly Internet: friendly@hotspur.psych.yorku.ca (NeXTmail OK) Psychology Department York University Voice: 416 736-5118 4700 Keele Street http://www.math.yorku.ca/SCS/friendly.html Toronto, ONT M3J 1P3 CANADA

Back to: Top of message | Previous page | Main SAS-L page