Page 1 of 1

Rounding to the next power of two

Posted: Fri Jun 04, 2021 8:12 pm
by ❤x1

Code: Select all

Procedure RoundPow(Number)
	Number - 1
	Number = (Number | Number >> 1)
	Number = (Number | Number >> 2)
	Number = (Number | Number >> 4)
	Number = (Number | Number >> 8)
	Number = (Number | Number >> 16)
	
	CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
		Number = (Number | Number >> 32)
	CompilerEndIf
	
	ProcedureReturn Number + 1
EndProcedure

Debug RoundPow(67)

Re: Rounding to the next power of two

Posted: Tue Jun 08, 2021 10:39 pm
by eck49
Clever!

A very elegant application of binary arithmetic.

Re: Rounding to the next power of two

Posted: Wed Jun 09, 2021 1:49 am
by BarryG
Since I'm a bit dumb, when would you need this type of trick? Can you give an example? I like to learn. Thanks.

Re: Rounding to the next power of two

Posted: Wed Jun 09, 2021 1:54 am
by Keya
I think you can also use the Intel assembly instruction "bsr" (bitscan reverse) for this

Re: Rounding to the next power of two

Posted: Wed Jun 09, 2021 1:58 am
by skywalk
This is faster than the direct way with pow() function. I will use it. :)
Useful when sampling discretely and FFT samples must be powers of 2.

Re: Rounding to the next power of two

Posted: Wed Jun 09, 2021 3:07 am
by idle
Yes a nice tip if you need to call it frequently the assembly equivalent would be like this.

Code: Select all

Procedure RoundPowUP(Number) 
  CompilerIf SizeOf(Integer) = 8
    !mov rdx,[p.v_Number] 
    !sub rdx, 1
    !bsr qword rcx , rdx
    !add rcx,1
    !shl rax,cl 
  CompilerElse
    !mov edx,[p.v_Number] 
    !sub edx, 1
    !bsr qword ecx , edx
    !add ecx,1
    !shl eax,cl 
  CompilerEndIf   
  ProcedureReturn 
EndProcedure