Estouro de pilha, apesar da posição de chamada final, mas apenas em 64 bits
Originado deessa questão, Eu tenho esse pequeno código F # (github) para gerar valores aleatórios de acordo com uma distribuição normal:
// val nextSingle : (unit -> float32)
let nextSingle =
let r = System.Random()
r.NextDouble >> float32
// val gauss : (float32 -> float32 -> seq<float32>)
let gauss mean stdDev =
let rec gauss ready = seq {
match ready with
| Some spare ->
yield spare * stdDev + mean
yield! gauss None
| _ ->
let rec loop () =
let u = nextSingle() * 2.f - 1.f
let v = nextSingle() * 2.f - 1.f
let s = pown u 2 + pown v 2
if s >= 1.f || s = 0.f then loop() else
u, v, s
let u, v, s = loop()
let mul = (*)(sqrt(-2.f * log s / s))
yield mul u * stdDev + mean
yield! mul v |> Some |> gauss
}
gauss None
Para mim, parece que isso deve se chamar apenas na posição de chamada de cauda, portanto nunca causa umStackOverflowException
quando o TCO está ativado. Mas issofaz ao correr64 bits. istonão ao correr32 bits (ou seja, caixa de seleção "Preferir 32 bits" nas configurações do projeto).
Estou usando o .NET Framework 4.5.2 e o F # 4.4.0.0.
Alguém pode explicar o que está causando o problema?