what's the easiest way to round up to power of 2?

BlitzMax Forums/BlitzMax Programming/what's the easiest way to round up to power of 2?

Grey Alien(Posted 2007) [#1]
Hiya, say I'm given a number in the range 0-1024, what's the easiest way to round it up to the next power of 2 value (aside from having an array (or loop) or ^2 values and comparing the given value against them). Thanks!


tonyg(Posted 2007) [#2]
This is how Bmax does it
		Function Pow2Size( n )
			Local t=1
			While t<n
				t:*2
			Wend
			Return t
		End Function

<edit> Notice you say without an array or loop then you're limiting yourself somewhat to possible solutions.


Grey Alien(Posted 2007) [#3]
what a handy function! Thanks TonyG, glad to see you are on the ball this morning.

Yeah just thought theere might be a fancy maths way without a loop.

Hey I that funciton won't compile, which module is it in?


Dreamora(Posted 2007) [#4]
Its no function that you can access, its a function within one of the GL functions (I think the gltexsize calculation function)

But you can easily put it into your own files or into the function that actually needs this function :-)


PS: YES, BM has some strange features like functions within methods and functions ^^


Grey Alien(Posted 2007) [#5]
I'll make it into a common code function then, thx.


CS_TBL(Posted 2007) [#6]
I've used this one for my texturegenerator:
Function BPo2:Int(v:Int)
	If v<0 v=0
	Local c:Int=1
	While v>0
		v=v Shr 1
		c=c Shl 1
	Wend
	Return c Shr 1
End Function


Dunno if it's any faster or slower. I'm not sure whether it's actually the correct solution either .. it finds the biggest power of 2 from a value. :P


TaskMaster(Posted 2007) [#7]
Without a loop.

Get the square root of your number. Round up the result and square it.

Square root is a slow process, so I have no idea if this would be faster or slower.


Warpy(Posted 2007) [#8]
TaskMaster, that won't give you a power of 2, it'll give you a perfect square. A power of 2 is a number of the form 2^x, not x^2.


Koriolis(Posted 2007) [#9]
Indeed, you need to rplace "square root" with "base 2 logarithm".
This would give:
Const LOG2# = 0.69314718055994529
Function BPo2:Int(v:Int)
	Return 1 Shl Int(Ceil(Log(v)/LOG2))
End Function
But this is clearly slower.


dmaz(Posted 2007) [#10]
this should be the fastest solution...
Function p:Int( n:Int )
	n :- 1
	n :| (n Shr 1)
	n :| (n Shr 2)
	n :| (n Shr 4)
	n :| (n Shr 8)
	n :| (n Shr 16)
	Return n+1
End Function

might have to be reversed on a powerpc mac though.


TaskMaster(Posted 2007) [#11]
Whoops, yep. What was I thinking. LOL


Czar Flavius(Posted 2007) [#12]
If the range is fixed, and you want speed, wouldn't a series of if (x >= n and x < m) statements for each part of the range be the fatest solution?


Grey Alien(Posted 2007) [#13]
dmaz: Nice. Mind you I don't actually need speed :-)