Search code examples
cmathnormalization

How to normalize my integer array from 0 to 10 in C


I have an array of integers ranging from some minimum to some maximum. I want to rescale them so that the minimum scales to 0, the maximum to 10, and in-between numbers scale to the nearest integer between 0 and 10, linearly.

There's no syntax error, but the code doesn't work as intended.

int main()
{
    int d,k,m;
int B[20];
int A[] = { -3, 200, -22, 4, 5, 300, 2, 5, 4, 5, -1, 2, 3, 4, 7, 4, 2, 0, 7, -3 };

int i = 0, j = 0;
int maxval = 0;
for (i=0; i<20; i++) 
{ 
    if (A[i] > maxval) 
    maxval = A[i]; 
}
int minval = maxval;
for (i=0; i<20; i++) 
{ 
    if (A[i] < minval) 
    minval=A[i];
}
d=(maxval-minval)/10;
printf("minval= %d\nmaxval= %d\nd=%d ", minval, maxval, d);



for (i=0; i<20; i++) 
{   m=minval;
    for(k=0;k<10;k++)
    {
        if(A[i]>m && A[i]<(m+d))
        B[i]=k;

    }
    m+=d;

}

for (i=0; i<20; i++) 
{ 
    printf("%d ", A[i]);
}

return 0;
}

Solution

  • I believe this is correct, but it's been over 20 years since I did this kind of integer math (on a minicomputer where integer math was the only kind of math you had).

    #include <stdio.h>
    
    int main()
    {
        /* Input data */
        int A[] = {
            -3, 200, -22, 4, 5, 300, 2, 5, 4, 5,
            -1, 2, 3, 4, 7, 4, 2, 0, 7, -3
        };
        int target_min = 0;
        int target_max = 10;
    
        /* Working variables */
        int nelems;
        int i;
        int source_min;
        int source_max;
        int source_scale;
        int target_scale;
        int zsrc;
        int scaled;
    
        nelems = sizeof(A) / sizeof(A[0]);
    
        source_min = source_max = A[0];
        for (i = 1; i < nelems; i++) {
            if (A[i] < source_min)
                source_min = A[i];
            if (A[i] > source_max)
                source_max = A[i];
        }
    
        if (source_min == source_max) {
            printf("Cannot scale: all values are the same\n");
            return -1;
        }
    
        source_scale = source_max - source_min;
        target_scale = target_max - target_min;
    
        /* The heart of the algorithm: scale everything.
           First, translate to a source_scale starting at zero.
           Second, scale to target_scale (also starting at zero).
           Third, translate to desired target scale.
    
           Scaling is done with integer math. Can round three ways; leave
           the desired one uncommented.
        */
    
        for (i = 0; i < nelems; i++) {
            zsrc = A[i] - source_min;
    
            // Round down
            //scaled = zsrc * target_scale / source_scale;
    
            // Round up
            //scaled = (zsrc * target_scale + source_scale - 1) / source_scale;
    
            // Round to nearest; if exactly halfway, rounds up
            scaled = (zsrc * target_scale * 2 + source_scale) / source_scale / 2;
    
            A[i] = scaled + target_min;
        }
    
        for (i = 0; i < nelems; i++) {
        printf("%d ", A[i]);
        }
        printf("\n");
    
        return 0;
    }