I want to add a special scaling mode where it snaps to the closest multiple. Right now, scaling up is fine, it's linear and goes something like this:
// f(x := 35, n := 32) = 32
// f(x := 66, n := 32) = 64
x = floor(x / n) * n
But for scaling down, I want some sort of inverse exponential:
// f(x := 18, n := 32) = 16
// f(x := 12, n := 32) = 8
// f(x := 7, n := 32) = 4
An implementation suggestion without using a loop in any language would suffice. My current implementation is as follows (which 100% works):
float ScaleMultiple(float value, float multiple) {
if (value > multiple) {
return(floor(value / multiple) * multiple);
} else if (value < multiple) {
do {
multiple /= 2.0f;
} while (value >= multiple);
return(multiple);
} else {
return(value);
}
}
multiple
is a positive floating point number and not necessarily a multiple of 2 and is at least equal to 1. value
is a positive floating point number and is at least equal to 1.
32 / 18 ~= 1.8 ~= 2, the result you want is 32 / 2, right? For the case of 12 and 32, this would yield 3 though, not four. In order to get there, take the log-2 of that number, round that to an even number and then convert back. However, this has the problem that it doesn't work properly when n
is not a power of two.
You can get the correct results for the values you give in Java as follows:
int f = (int)Math.pow(2,(int)(Math.log(x)/Math.log(2)));
There's insufficient information provided to answer the question for arbitrary n.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.