Share your advanced PureBasic knowledge/code with the community.
❤x1
User
Posts: 46 Joined: Thu Jan 10, 2019 5:56 pm
Post
by ❤x1 » Fri Jun 04, 2021 8:12 pm
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)
eck49
Enthusiast
Posts: 153 Joined: Sat Nov 14, 2020 10:08 pm
Location: England
Post
by eck49 » Tue Jun 08, 2021 10:39 pm
Clever!
A very elegant application of binary arithmetic.
Ubuntu 22.04 64-bit
Purebasic 6.00 (as of 5 Sep 2022)
(native tongue: English)
BarryG
Addict
Posts: 3330 Joined: Thu Apr 18, 2019 8:17 am
Post
by BarryG » Wed Jun 09, 2021 1:49 am
Since I'm a bit dumb, when would you need this type of trick? Can you give an example? I like to learn. Thanks.
Keya
Addict
Posts: 1891 Joined: Thu Jun 04, 2015 7:10 am
Post
by Keya » Wed Jun 09, 2021 1:54 am
I think you can also use the Intel assembly instruction "bsr" (bitscan reverse) for this
skywalk
Addict
Posts: 4003 Joined: Wed Dec 23, 2009 10:14 pm
Location: Boston, MA
Post
by skywalk » Wed Jun 09, 2021 1:58 am
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.
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
idle
Always Here
Posts: 5097 Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand
Post
by idle » Wed Jun 09, 2021 3:07 am
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