Fast InvSqrt in Max

BlitzMax Forums/BlitzMax Programming/Fast InvSqrt in Max

The forum is locked. These are the original blitzbasic.com forums, kept so they can still be read. No new topics, replies or edits can be made here. To join in, head over to the Blitz3D+ forums.

The InvSqr numbers look good but the SQR numbers are quite a bit off (the results of the functions)

EDIT: this is the same as Knotz's first post but also shows a result for comparison of accuracy.

Function InvSqrtKnotz:Float(x:Float)

	Local xhalf:Float = 0.5*x
	Local i:Int = (Int Ptr(Varptr(x)))[0]
	i = $5f3759df - (i Shr 1)
	x = (Float Ptr(Varptr(i)))[0]
	x = x*(1.5 - xhalf*x*x)
	Return x

End Function

Function InvSqrtAntMan:Float(x:Float)

	Local i = $5f3759df - (Int Ptr(Varptr(x))[0] Shr 1)
	Local ox:Float = (Float Ptr(Varptr(i))[0])
	Return  ox *(1.5 - ((0.5*x)*ox*ox))
	
End Function

Function InvSqrtFredborg:Float(x:Float)

	Local i:Int = $5f3759df - (Int Ptr(Varptr(x))[0] Shr 1)
	Return  (Float Ptr(Varptr(i))[0]) *(1.5 - ((0.5*x)*(Float Ptr(Varptr(i))[0])*(Float Ptr(Varptr(i))[0])))
	
End Function

Function InvSqrtSOS:Float(x:Float)

    Local xhalf:Float = 0.5*x
	Local i:Int = $5f3759df - (Int Ptr(Varptr(x))[0] Shr 1)
	Local ox:Float = (Float Ptr(Varptr(i))[0])
	Return ox *(1.5 - (xhalf*ox*ox))
	
End Function

Function InvSqrtAza:Float(x:Float)

	Local xhalf:Float = 0.5*x
	Local ip:Int Ptr=Int Ptr(Varptr(x))
	ip[0]=$5f3759df-(ip[0] Shr 1)
	Return x *(1.5 - (xhalf*x*x))

End Function

Function InvSqrtPlain:Float(x:Float)

	Return 1.0/Sqr(x)
	
End Function

Function SqrtKnotz:Float(x:Float)

	Local xhalf:Float = 0.5*x
	Local i:Int = (Int Ptr(Varptr(x)))[0]
	i = ($be6f0000 - i) Shr 1
	x = (Float Ptr(Varptr(i)))[0]
	x = x*(1.5 - xhalf*x*x)
	Return x

End Function

Function SqrtAntMan:Float(x:Float)

	Local i = ($be6f0000 - (Int Ptr(Varptr(x))[0])) Shr 1
	Local ox:Float = (Float Ptr(Varptr(i))[0])
	Return  ox *(1.5 - ((0.5*x)*ox*ox))
	
End Function

Function SqrtFredborg:Float(x:Float)

	Local i:Int = ($be6f0000 - (Int Ptr(Varptr(x))[0])) Shr 1
	Return  (Float Ptr(Varptr(i))[0]) *(1.5 - ((0.5*x)*(Float Ptr(Varptr(i))[0])*(Float Ptr(Varptr(i))[0])))
	
End Function


Function SqrtSOS:Float(x:Float)

    Local xhalf:Float = 0.5*x
	Local i:Int = ($be6f0000 - (Int Ptr(Varptr(x))[0])) Shr 1
	Local ox:Float = (Float Ptr(Varptr(i))[0])
	Return ox *(1.5 - (xhalf*ox*ox))
	
End Function

Function SqrtAza:Float(x:Float)

	Local xhalf:Float = 0.5*x
	Local ip:Int Ptr=Int Ptr(Varptr(x))
	ip[0]=($be6f0000 - ip[0]) Shr 1
	Return x *(1.5 - (xhalf*x*x))

End Function

Function SqrtPlain:Float(x:Float)

	Return Sqr(x)
	
End Function

Function Benchmark(label:String, func:Float(x:Float))

	Local startTime:Long = MilliSecs()
	For Local ii:Int=1 To 10000000
		func(Float(ii))
	Next
	Local endTime:Long = MilliSecs() - startTime
	Local result:Float = func(5.0)
	Print label + ":~t~t" + endTime + "ms" + "~t~tfunc(5.0):"+result


End Function

Print "~nInvSqrt:"
'Benchmark("Raw C",InvSqrt)
Benchmark("Knotz   ",InvSqrtKnotz)
Benchmark("Artman  ",InvSqrtAntman)
Benchmark("Fredborg",InvSqrtFredborg)
Benchmark("SOS     ",InvSqrtSOS)
Benchmark("Azathoth",InvSqrtAza)
Benchmark("1/Sqr() ",InvSqrtPlain)


Print "~nSqrt:"
'Benchmark("Raw C",Sqrt)
Benchmark("Knotz   ",SqrtKnotz)
Benchmark("Artman  ",SqrtAntman)
Benchmark("Fredborg",SqrtFredborg)
Benchmark("SOS     ",SqrtSOS)
Benchmark("Azathoth",SqrtAza)
Benchmark("Sqr()   ",SqrtPlain)