0
$\begingroup$

How do I find an exponent of $2$ that when multiplied with another number would bring the result closest to the positive side $1$? Like this: $y = x \cdot 2^a$, where $y\ge 1$ has to be as small as possible, $x \in \mathbb R\setminus \{0\}$, and $a$ is the variable to determine.

This is for a program algorithm where I generate an infinitely zooming grid and x is the scale. Currently I just do this:

while (tScale > 1) {
    tScale /= 2;
}
while (tScale < 1) {
    tScale *= 2;
}

Since I was lazy at the time but I figured it must be rather inefficient and there's probably a more direct way to get the value.

$\endgroup$
  • $\begingroup$ Please let me know if you meant $y = x\cdot 2^e$. Using $a$ instead of $e$ would be a better choice of variable, since $e$ usually denotes the mathematical constant $e$. $\endgroup$ – Namaste Jun 23 '14 at 13:34
  • $\begingroup$ oh yes probably a then, I certainly didn't mean any constant. $\endgroup$ – Karl Smith Jun 23 '14 at 13:35
  • $\begingroup$ I edited it just now, y = 1 is a valid result. If y is 1 to begin with it just skips the 2 loops. $\endgroup$ – Karl Smith Jun 23 '14 at 13:45
  • $\begingroup$ Yes, I saw the edit. The main problem I see is that depending on $y$, multiplying or dividing by $2$ may still lead to infinite looping, if the value you are multiplying or dividing is irrational. $\endgroup$ – Namaste Jun 23 '14 at 13:48
  • $\begingroup$ I don't get what you mean. I see 3 options: 1. y is bigger than 1, then y gets divided by 2 until its not and then multiplied again until its greater(just once in this case) 2. y is smaller than 1, then y skips the first loop and is multiplied by 2 until it is greater. 3. y is 1 in which case it just skips the whole thing. $\endgroup$ – Karl Smith Jun 23 '14 at 13:52
1
$\begingroup$

OP figured it out with the help of amWhy in comments:

var exp = Math.ceil(Math.log(1 / scale) / Math.log(2)); 
var tScale = Math.pow(2, exp) * scale; 

"Works great". The equivalent in math terms: $a = \lceil \ln(1 / x) / \ln(2)\rceil$.


That said, I'm pretty sure that the original code in the question is actually faster. Computing logarithms in double precision and then throwing out the fractional part does not look like an efficient thing to do.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.