Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!sun-barr!newstop!texsun!convex!convex.COM From: dodson@convex.COM (Dave Dodson) Newsgroups: comp.lang.fortran Subject: Re: rounding a real to a whole number Message-ID: <108130@convex.convex.com> Date: 2 Nov 90 17:01:21 GMT References: Sender: usenet@convex.com Reply-To: dodson@convex.COM (Dave Dodson) Organization: Convex Computer Corporation; Richardson, TX Lines: 80 In article u714092@eagle.larc.nasa.gov (prichard devon ) writes: >what I want to do is to have a subroutine which, given a range of real >numbers, for example -123.445 -> 1033.02 , and choose whole numbers >outside that range. obviously the first application is axis values for >x-y plots. optionally, picking a 10-multiple of whole numbers ought to >be included; for -1.45567 -> 3.34112 , it should return -1.4 and 3.4 ... If you are going to plot data, you may want the axis divisions to be "round" numbers. I wrote a subroutine many years ago that determined such an axis. The following is how I remember it working. Caution: not checked out... subroutine axis (n,x,ndiv,xmin,delx,xmax) c input: integer n ! length of x integer ndiv ! number of axis divisions real x(n) ! data array c output: real xmin ! axis minimum, multiple of delx real delx ! axis increment per division real xmax ! axis maximum, multiple of delx c local: real table(4) data table / 1.0, 2.0, 4.0, 5.0 / xmini = x(1) xmaxi = x(1) do 10 i = 2, n xmini = min ( xmini, x(i) xmaxi = max ( xmaxi, x(i) 10 continue if ( xmini .eq. xmaxi ) then < I don't remember what I did when all x(i) are equal > end if delta = ( xmaxi - xmini ) / ndiv ratio = 0.0 do 40 i = 1, 4 trial = table(i) 20 if ( trial .lt. delta ) then trial = 10.0 * trial go to 20 end if 30 if ( trial / 10.0 .gt. delta ) then trial = trial / 10.0 go to 30 end if xmint = trial * aint ( xmini / trial ) if ( xmint .gt. xmini ) xmint = xmint - trial xmaxt = trial * aint ( xmaxi / trial ) if ( xmaxt .lt. xmaxi ) xmaxt = xmaxt + trial if ( xmint + ndiv * trial * 1.0001 .ge. xmaxt ) then if ( ( xmaxi - xmini ) / ( xmaxt - xmint ) .gt. ratio ) then ratio = ( xmaxi - xmini ) / ( xmaxt - xmint ) xmin = xmint delx = trial xmax = xmaxt end if end if 40 continue return end This begins by finding the max and min of the data. Delta is set to the minimum allowed increment per axis division. Ratio is the fraction of the axis that would be occupied by the graph; it is initialized to zero. Then each increment of the form 1 * 10^j, 2 * 10^j, and 4 * 10^j is examined. First the j in 10^j is adjusted up or down so that table(i) * 10^(j-1) <= delta <= table(i) * 10^j (actually, we don't care about j, only trial := table(i) * 10^j). Using trial as an increment per axis division, we find xmint = the largest multiple of trial that is .le. xmini and xmaxt = the smallest multiple of trial that is .ge. xmaxt. If ndiv * trial spans the interval from xmint to xmaxt then we check to see how much of the axis would be occupied by the graph. We accept trial if it uses more axis that the previous. When we have inspected all 4 forms for trial, we return with the best one. ---------------------------------------------------------------------- Dave Dodson dodson@convex.COM Convex Computer Corporation Richardson, Texas (214) 497-4234