I have uint16_t integers in the range [ 0 .. 4092 ] and I need to scale them into [ 0 .. 255 ] interval.
What’s the correct formula for that?
The obvious one y = x * 255 / 4092 doesn’t work because the scaling factor is 15.988 so I need 15-16 (usually 16, rarely 15) input values mapped into every output value. With that formula the output 255 only produced for a single input value.
The less obvious formula, which uses an offset to round to nearest, y = ( x * 255 + 2045 ) / 4092, doesn’t work either because the output 255 corresponds to 9 input values [ 4084 .. 4092 ], again that’s not what I want, I want 15 or 16 input numbers mapped into each output number.
BTW, I have gigabytes of these numbers in memory, for this reason I’d rather not use floating point math for this.
>Solution :
Try multiplying and dividing by one more than you currently are. This code seems to produce your expected results:
#include <iostream>
using namespace std;
int main() {
for (int i = 0; i <= 4092; ++i)
cout << (i<<8)/4093 << endl; // i<<8 is equivalent to i*256
}