Skip to content

Instantly share code, notes, and snippets.

@hodzanassredin
Created March 1, 2021 14:11
Show Gist options
  • Save hodzanassredin/4b60ecffcd6b717763a683ad00bbc0ba to your computer and use it in GitHub Desktop.
Save hodzanassredin/4b60ecffcd6b717763a683ad00bbc0ba to your computer and use it in GitHub Desktop.
open System
type Number = uint
let radixPointBits = 8
let minusOne = UInt32.MaxValue
let negateSlow (n:Number) : Number =
let mutable res = 0u
for i in 0u..n do
res <- res + minusOne
res
let negate (n:Number) : Number = (~~~ n) + 1u
assert (negate 1u = UInt32.MaxValue)
let MaxValue = UInt32.MaxValue / 2u
let MinValue = negate MaxValue - 1u// or MaxValue+1u
assert (MaxValue + 1u = MinValue)
let isNegative1 (n:Number) = n > MinValue
let nagativeBit = (uint)1 <<< 31
let isNegative (n:Number) = (n &&& nagativeBit) > 0u
let rec toInt (n:Number) : int = if isNegative n then -(toInt (negate n)) else (int)(n>>>radixPointBits)
let rec toNumber (n:int) : Number = if n >= 0 then (uint) (n<<<radixPointBits) else toNumber -n |> negate
let add (a:Number) (b:Number) = a + b
let minus (a:Number) (b:Number) = add a (negate b)
minus (toNumber 1) (toNumber -2) |> toInt // 3
add (toNumber 1) (toNumber -2) |> toInt//-1
let rec fold (f:('State -> 'State)) (state: 'State) (n: Number) : 'State =
match n with
| 0u -> state
| _ -> fold f (f state) (n-1u)
let rec unfold (f:('State -> 'State option)) (state:'State) : Number =
match (f state) with
| None -> 0u
| Some(state) -> unfold f state + 1u
//let inc = add 1u
//let dec x = add x (negate 1u)
//let sum a b = fold inc a b
let mul a b = (fold (add a) 0u b)>>>radixPointBits
mul (toNumber 5) (toNumber 3) |> toInt//15
mul (toNumber 5) (toNumber -3) |> toInt//-15 but not as fast, can be optimized
let fold_fast (f:('State -> 'State)) (state: 'State) (n: Number) : 'State =
if isNegative n then fold f state (negate n) |> negate
else fold f state n
let mul_fast a b = (fold_fast (add a) 0u b) >>> radixPointBits
mul_fast (toNumber 5) (toNumber -3) |> toInt//-15 but not as fast, can be optimized
//let oneDivBy (n:Number) : Number =
for i in 0u..100u do
printfn "%d -> %d" i (~~~ i)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment