Skip to content

Instantly share code, notes, and snippets.

@sambrightman
Created May 2, 2020 09:26
Show Gist options
  • Save sambrightman/bf870d1c06df51bdaf62e1ee7dd9a5c5 to your computer and use it in GitHub Desktop.
Save sambrightman/bf870d1c06df51bdaf62e1ee7dd9a5c5 to your computer and use it in GitHub Desktop.
Square root implementations
import random
import math
import numpy
import ctypes
import struct
def test_math():
x = random.randint(0, 1000)
root = math.sqrt(x)
def test_numpy():
x = random.randint(0, 1000)
root = numpy.sqrt(x)
def ctypes_isqrt(number):
threehalfs = 1.5
x2 = number * 0.5
y = ctypes.c_float(number)
i = ctypes.cast(ctypes.byref(y), ctypes.POINTER(ctypes.c_int32)).contents.value
i = ctypes.c_int32(0x5f3759df - (i >> 1))
y = ctypes.cast(ctypes.byref(i), ctypes.POINTER(ctypes.c_float)).contents.value
y = y * (1.5 - (x2 * y * y))
return y
def struct_isqrt(number):
threehalfs = 1.5
x2 = number * 0.5
y = number
packed_y = struct.pack('f', y)
i = struct.unpack('i', packed_y)[0] # treat float's bytes as int
i = 0x5f3759df - (i >> 1) # arithmetic with magic number
packed_i = struct.pack('i', i)
y = struct.unpack('f', packed_i)[0] # treat int's bytes as float
y = y * (threehalfs - (x2 * y * y)) # Newton's method
return y
def numpy_isqrt(number):
threehalfs = 1.5
x2 = number * 0.5
y = numpy.float32(number)
i = y.view(numpy.int32)
i = numpy.int32(0x5f3759df) - numpy.int32(i >> 1)
y = i.view(numpy.float32)
y = y * (threehalfs - (x2 * y * y))
return float(y)
def test_numpy_fast():
x = random.randint(0, 1000)
root = numpy_isqrt(x)
def test_ctypes_fast():
x = random.randint(0, 1000)
root = ctypes_isqrt(x)
def test_struct_fast():
x = random.randint(0, 1000)
root = struct_isqrt(x)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment