fix(fsharp): mulberry32 wraps through uint64 so the Fable build matches the fixtures
Fable compiles uint32 * and + to plain JavaScript arithmetic (no wrap, inexact above 2^53); 2 of 37 RNG fixture cases matched in the browser build. uint64 helpers are exact on .NET and in Fable (BigInt). Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
ab8abaaa77
commit
527b2cd157
@@ -17,12 +17,14 @@ let map (f: 'a -> 'b) (r: Random<'a>) : Random<'b> = failwith "TODO m04"
|
||||
/// Run `r`, feed its value to `f` to pick the next Random, and run that with the seed `r` left behind.
|
||||
let bind (f: 'a -> Random<'b>) (r: Random<'a>) : Random<'b> = failwith "TODO m04"
|
||||
|
||||
/// The generator (mulberry32). uint32 arithmetic already wraps around at 2^32 and `>>>` on a uint32 is an
|
||||
/// unsigned shift. With `s = seed + 0x6D2B79F5u`:
|
||||
/// The generator (mulberry32). With `s = seed + 0x6D2B79F5u`:
|
||||
/// t = (s ^^^ (s >>> 15)) * (s ||| 1u)
|
||||
/// t = t ^^^ (t + (t ^^^ (t >>> 7)) * (t ||| 61u))
|
||||
/// value = t ^^^ (t >>> 14)
|
||||
/// It returns `value` and the new seed `s`.
|
||||
/// It returns `value` and the new seed `s`. Every `*` and `+` must wrap around at 2^32, and `>>>` on a uint32 is an
|
||||
/// unsigned shift. On .NET uint32 `*` and `+` already wrap, but the browser build (Fable) turns them into plain
|
||||
/// JavaScript arithmetic that does not, so write them as small helpers that go through uint64 and back, e.g.
|
||||
/// `let mul (a: uint32) (b: uint32) = uint32 (uint64 a * uint64 b)`; that is exact on both.
|
||||
/// (The stub is wrapped in `Random` so the TODO only fires when the generator is run.)
|
||||
let nextUint32: Random<uint32> = Random(fun _ -> failwith "TODO m04")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user