Best way to calc next ^2 value...

Blitz3D Forums/Blitz3D Programming/Best way to calc next ^2 value...

Floyd - Your version doesn't work as advertised here. I reckon you need '|' (bitwise OR) instead of 'Or' (conditional OR). Neat trick though.

I would have done it as in NextPower2(). We'd both have problems with the maximum integer value. And signed numbers are a bit iffy as well.

And NextPowerV3() is another variation. Pretty ugly but it just might be faster (haven't benchmarked it). There are many ways to arrange the search tree. The optimal depends upon the expected range of values.

If you have a small possible range of values a lookup table would be another way and probably the fastest so long as the number of calls is large enough to make up for the table initialisation.

Note that I've changed the numbers tested from 1-35 to a randon selection of 50 in the range 1-$3FFFFFFF.
Strict

Print "Starting"

Local iTest:Int

For iTest:Int = 1 To 50

	Local n:Int = Rand(1, $3FFFFFFF)
	
	Local v1:Int = NextPowerV1(n)
	Local v2:Int = NextPowerV2(n)
	Local v3:Int = NextPowerV3(n)
	
	Local msg:String
	
	If (v1 = v2) And (v1 = v3)
		msg = ""
	Else
		msg = "Error"
	EndIf
	
	Print RSet(iTest, 4) + RSet(n, 12) + RSet (v1, 12) + RSet(v2, 12) + RSet(v3, 12) + " " + msg
Next

Print "Finished"

Function NextPowerV1:Int(n:Int)
	n = n - 1
	n = n | ( n Shr 1 )
	n = n | ( n Shr 2 )
	n = n | ( n Shr 4 )
	n = n | ( n Shr 8 )
	n = n | ( n Shr 16 )
	Return n + 1
End Function

Function NextPowerV2:Int(n:Int)
	If n > $40000000
		Throw "Value too big"
	EndIf
	
	Local v:Int = 1
	While (v < n)
		v = v Shl 1
	Wend
	Return v
End Function

Function NextPowerV3:Int(n:Int)
	If n < 1
		Throw "Value too low"
	EndIf
	
	If n <= $10
		If n <= $8
			If n <= $4
				If n <= $2
					If n <= $1
						Return $1
					Else
						Return $2
					EndIf
				Else
					Return $4
				EndIf
			Else
				Return $8
			EndIf
		Else
			Return $10
		EndIf
	Else If n <= $100
		If n <= $80
			If n <= $40
				If n <= $20
					Return $20
				Else
					Return $40
				EndIf
			Else
				Return $80
			EndIf
		Else
			Return $100
		EndIf
	Else If n <= $1000
		If n <= $800
			If n <= $400
				If n <= $200
					Return $200
				Else
					Return $400
				EndIf
			Else
				Return $800
			EndIf
		Else
			Return $1000
		EndIf
	Else If n <= $10000
		If n <= $8000
			If n <= $4000
				If n <= $2000
					Return $2000
				Else
					Return $4000
				EndIf
			Else
				Return $8000
			EndIf
		Else
			Return $10000
		EndIf
	Else If n <= $100000
		If n <= $80000
			If n <= $40000
				If n <= $20000
					Return $20000
				Else
					Return $40000
				EndIf
			Else
				Return $80000
			EndIf
		Else
			Return $100000
		EndIf
	Else If n <= $1000000
		If n <= $800000
			If n <= $400000
				If n <= $200000
					Return $200000
				Else
					Return $400000
				EndIf
			Else
				Return $800000
			EndIf
		Else
			Return $1000000
		EndIf
	Else If n <= $10000000
		If n <= $8000000
			If n <= $4000000
				If n <= $2000000
					Return $2000000
				Else
					Return $4000000
				EndIf
			Else
				Return $8000000
			EndIf
		Else
			Return $10000000
		EndIf
	Else
		If n <= $40000000
			If n <= $20000000
				Return $20000000
			Else
				Return $40000000
			EndIf
		Else
			Throw "Value too big"
		EndIf
	EndIf
	
End Function