So if I have a range of numbers \'0 - 1024\' and I want to bring them into \'0 - 255\', the maths would dictate to divide the input by the maximum the input will be (1024 in
In your case n/1024
results in 0 as you are doing integer division. To overcome this you can cast n
to float
. This will give you a result between 0.0
and 1.0
next you multiply with 255
and cast the result back to integer. Also you need to declare scale
as int
int scale;
int n = 80;
scale = (int)(((float)n/1024) * 255);
It's because you're doing integer division.
Divide by a double or a float, and it will work:
double scale = ( n / 1024.0 ) * 255 ;
Or, if you want it as a float,
float scale = ( n / 1024.0f ) * 255 ;
n / 1024 is integer division, which yields an integer (ie. 0 in this case).
Use n / 1024.0
instead.
others have given great answers already. In case you want your scale to be an integer (which makes sense if your n is an integer already), you could do
int scale = ((255 * n)/1024);
Note that you won't hit any problems with this as long as these are the numbers, since n * 255 will always fit in an int when the maximum n = 1024.
more flexible would be
int scale(int value, int old_max, int new_max){
java.math.BigInteger big_value = java.math.BigInteger.valueOf(value);
java.math.BigInteger big_old_max = java.math.BigInteger.valueOf(old_max);
java.math.BigInteger big_new_max = java.math.BigInteger.valueOf(new_max);
java.math.BigInteger mult = big_value.multiply(big_old_max);
return (int) mult.devide(big_new_max).doubleValue();
}
You won't overflow any ints this way, though I admit this is a bit verbose
Edit:
Basicly the same, but less clunky (though for very high numbers you might run into some precission errors)
int scale(int value, int old_max, int new_max){
double factor = (double) new_max / (double) old_max;
return factor * value;
}
I presume n
is an int
. Because the constants 1024 and 255 are both int
s all the right-hand side calculations are being done with integer arithmetic. Meaning the result of n/1024
is being truncated to a integral value before being multiplied by 255
.
Any of these modifications will make the calculations work correctly:
scale = n / 1024.0 * 255.0; // Use double constants.
scale = (double) n / 1024 * 255; // Convert n to a double.
scale = n * 255 / 1024; // Multiply before dividing.
The last one uses integer math still but switching the order of operations means you won't get the undesired truncation to 0. You'll still only get integer answers though, so you'll lose any decimal points in the answers.
You should auto-cast n to float by means of a multiplication FIRST, otherwise you're doing an integer operation and then casting the result, instead of doing the operation between floats.
float scale;
scale = n * 1.0 / 1024 * 255;