Skip to content

Instantly share code, notes, and snippets.

@mattn
Last active July 25, 2016 06:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mattn/f3049da987cca4648b2cfcaca6bdf180 to your computer and use it in GitHub Desktop.
Save mattn/f3049da987cca4648b2cfcaca6bdf180 to your computer and use it in GitHub Desktop.
function! s:fastinvsqrt(x)
let x = str2float(string(a:x))
let s = x < 0
if s
let x = x * -1
endif
let exp = float2nr(log(x) / 0.6931471805599453 + 127.0)
let frac = float2nr(x * pow(2, 150.0 - exp))
let b = ''
while frac > 0
let b = (float2nr(frac) % 2) . b
let frac = frac / 2
endwhile
let fb = b
let b = ''
while exp > 0
let b = (float2nr(exp) % 2) . b
let exp = exp / 2
endwhile
let eb = ("000000000" . b)[-8:]
let fb .= repeat('0', 30-len(eb)-len(fb))
let fb = fb[-23:]
let fb = ((s ? '1' : '0') . eb) . fb
let r = '0b' . fb + 0
let r = 0x5f3759df - (r / 2)
let b = ''
while r > 0
let b = (float2nr(r) % 2) . b
let r = r / 2
endwhile
let b = repeat('0', 31-len(b)) . b
let b = (r > 0 ? '1' : '0') . b
let s = b[0]
let exp = ('0b' . b[1:8]) - 127.0
let frac = eval('0b' . b[9:])
let y = eval('1.' . frac) * pow(2.0, exp)
return y * (1.5 - 0.5 * x * y * y)
endfunction
echo s:fastinvsqrt(100)
echo s:fastinvsqrt(10)
echo s:fastinvsqrt(1)
echo s:fastinvsqrt(0.1)
echo s:fastinvsqrt(0.01)
echo s:fastinvsqrt(0.0025)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment