7 people like it.

Fast inverse square root

This is an implementation of the famous 'magic number' method of rapidly calculating (inverse) square roots. (See http://en.wikipedia.org/wiki/Fast_inverse_square_root.) In practice, this version is no faster in F# than using 1./sqrt(x). I've posted it as an example of how you can get down-and-dirty with the bits in F# if you need to.

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
let fastInvSqrt (n : float32) : float32 =
    let MAGIC_NUMBER : int32 = 0x5f3759df 
    let THREE_HALVES = 1.5f
    let x2 = n * 0.5f
    let i = MAGIC_NUMBER - (System.BitConverter.ToInt32(System.BitConverter.GetBytes(n), 0) >>> 1)
    let y = System.BitConverter.ToSingle(System.BitConverter.GetBytes(i), 0)
    y * (THREE_HALVES - (x2 * y * y))

// Examples:

let x = fastInvSqrt 4.0f
// Output: val x : float32 = 0.499153584f

let x' = 1. / sqrt(4.0)
// Output: val x' : float = 0.5
val fastInvSqrt : n:float32 -> float32

Full name: Script.fastInvSqrt
val n : float32
Multiple items
val float32 : value:'T -> float32 (requires member op_Explicit)

Full name: Microsoft.FSharp.Core.Operators.float32

--------------------
type float32 = System.Single

Full name: Microsoft.FSharp.Core.float32

--------------------
type float32<'Measure> = float32

Full name: Microsoft.FSharp.Core.float32<_>
val MAGIC_NUMBER : int32
Multiple items
val int32 : value:'T -> int32 (requires member op_Explicit)

Full name: Microsoft.FSharp.Core.Operators.int32

--------------------
type int32 = System.Int32

Full name: Microsoft.FSharp.Core.int32
val THREE_HALVES : float32
val x2 : float32
val i : int32
namespace System
type BitConverter =
  static val IsLittleEndian : bool
  static member DoubleToInt64Bits : value:float -> int64
  static member GetBytes : value:bool -> byte[] + 9 overloads
  static member Int64BitsToDouble : value:int64 -> float
  static member ToBoolean : value:byte[] * startIndex:int -> bool
  static member ToChar : value:byte[] * startIndex:int -> char
  static member ToDouble : value:byte[] * startIndex:int -> float
  static member ToInt16 : value:byte[] * startIndex:int -> int16
  static member ToInt32 : value:byte[] * startIndex:int -> int
  static member ToInt64 : value:byte[] * startIndex:int -> int64
  ...

Full name: System.BitConverter
System.BitConverter.ToInt32(value: byte [], startIndex: int) : int
System.BitConverter.GetBytes(value: float) : byte []
System.BitConverter.GetBytes(value: float32) : byte []
System.BitConverter.GetBytes(value: uint64) : byte []
System.BitConverter.GetBytes(value: uint32) : byte []
System.BitConverter.GetBytes(value: uint16) : byte []
System.BitConverter.GetBytes(value: int64) : byte []
System.BitConverter.GetBytes(value: int) : byte []
System.BitConverter.GetBytes(value: int16) : byte []
System.BitConverter.GetBytes(value: char) : byte []
System.BitConverter.GetBytes(value: bool) : byte []
val y : float32
System.BitConverter.ToSingle(value: byte [], startIndex: int) : float32
val x : float32

Full name: Script.x
val x' : float

Full name: Script.x'
val sqrt : value:'T -> 'U (requires member Sqrt)

Full name: Microsoft.FSharp.Core.Operators.sqrt
Next Version Raw view Test code New version

More information

Link:http://fssnip.net/9M
Posted:12 years ago
Author:Kit Eason
Tags: fast inverse square root; bitwise