1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
/*
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 <math.h>
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);
}
|