/* SUBROUTINE SCALE(FMN, FMX, N, VALMIN, STEP, VALMAX, IFAULT) ALGORITHM AS 96 APPL. STATIST. (1976) VOL.25, NO.1 Given extreme values FMN, FMX, and the need for a scale with N marks, calculates value for the lowest scale mark (VALMIN) and step length (STEP) and highest scale mark (VALMAX). */ #include int scale(float fmn, float fmx, int n, float *valmin, float *step, float *valmax) { float unit[12]={0.0, 1.0, 1.2, 1.6, 2.0, 2.5, 3.0, 4.0, 5.0, 6.0, 8.0, 10.0}; int i, j, ifault, nunit=11;; float tol=5.0e-6; float bias=1.0e-4; float fmax, fmin, rn, x, s, range; fmax=fmx; fmin=fmn; ifault=1; /* Test for valid parameter values */ if ((fmax < fmin) || (n <= 1)) return(ifault); ifault=0; rn=(float)(n - 1.0); x=fabs(fmax); if (x == 0.0) x=1.0; if ((fmax-fmin)/x <= tol) { /* All values effectively equal */ if (fmax < 0.0) fmax=0.0; else if (fmax == 0.0) fmax=1.0; else fmin=0.0; } *step=(fmax-fmin)/rn; s=*step; /* Find power of 10 */ while (s<1.0) s*=10.0; while (s>=10.0) s/=10.0; /* Calculate STEP */ x=s-bias; i=1; while ((i<=nunit) && (x>unit[i])) i++; *step=(*step)*unit[i]/s; range=(*step)*rn; /* Make first estimate of VALMIN */ x=0.5 * (1.0 +(fmax+fmin-range)/(*step)); j=(int)(x-bias); if (x<0.0) j--; *valmin=(*step)*(float)j; /* Test if VALMIN could be zero */ if ((fmin >= 0.0) && (range >= fmax)) *valmin=0.0; *valmax=(*valmin)+range; /* Test if VALMAX could be zero */ if ((fmax > 0.0) || (range < (-1)*fmin)) return(ifault); *valmax=0.0; *valmin=(-1)*range; return(ifault); }