Skip to content

Instantly share code, notes, and snippets.

@hodzanassredin
Created April 15, 2019 13:22
Show Gist options
  • Save hodzanassredin/5f60c093905aa7a78dfa38899d3c076f to your computer and use it in GitHub Desktop.
Save hodzanassredin/5f60c093905aa7a78dfa38899d3c076f to your computer and use it in GitHub Desktop.
fixed point arithmetic in fsharp
open System
let scale (n3: int16) (n2: int16) (n1: int16) : int16 = (int n1) * (int n2) / (int n3) |> int16
let percent = scale 100s
let percent20 = percent 20s
let r = percent20 50s//10s
let test = 2000s * 34s / 100s//overflow 24s
let testFixed = percent 34s 2000s//680s
let roundedPercent percent value = (scale 10s value percent + 5s) / 10s
let testRounded = roundedPercent 32s 227s//73s
let test2 = 2.0f /3.0f * 171.0f//expected 113.9999 but 114
let test2Fixed = scale 3s 2s 171s//114
let test3 = 7.105/12.250 * 150.0//87.0
let test3Fixed = scale 12250s 7105s 150s //87s
let pi = scale 113s 355s
let e = scale 10546s 28667s
let testPi = pi 1000s//3141s
let testE = e 1000s//3141s
let square (r:double) = System.Math.PI * (r ** 2.)
let squareFixed x= pi ( x * x)
let testSquare = square 10.//314.1592654
let testSquareFixed = squareFixed 10s//314s
let _1 = 16384s
let inline (.*) (x:int16) (y:int16) = scale _1 y x
let inline (./) (x:int16) (y:int16) = scale y _1 x
let toDouble (x: int16) = x .* 10000s |> double |> fun x -> x / 10000.
let toFixed (x: double) : int16 = x * 10000. |> int16 |> fun x -> x ./ 10000s
let oneDivOneIsOne = 1s ./ 1s = _1//true
let oneDivTwoIsHalf = 1s ./ 2s = (_1 / 2s)//true
let testFractions = 7./34.+23./99.//0.4382055853
let testFractionsFixed = 7s ./ 34s + 23s ./ 99s |> toDouble//0.4381
let sqrtFixed (n:int16) =
let rec si (root: int16)=
let newRoot = (n ./ root + root) / 2s
if root = newRoot then root else si newRoot
si (1s./10s)
let sqrt = toFixed >> sqrtFixed >> toDouble
let testSqrt = Math.Sqrt(0.01)//0.1
let testSqrtFixed = sqrt 0.01//0.0997
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment