Math.Round(x) rounds imprecisely under Fable 5.26.0

Cerrado
#5,251 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Los mantenedores suelen responder en 1 día

Ya se ha fusionado un pull request relacionado.

  • #5254 de @MangelMaxime — fusionado

Evaluación

Dificultad
3/5
Tiempo estimado
1-2 días
Aptitud para principiantes
62/100
Tipo de issue
Error
Claridad
Bien especificado
Estado de actividad
Activo
Stack tecnológico
javascript
Área
compilers

Línea de trabajo

The bug is in the round helper of fable-library-js (Util.round), which uses toFixed(8) and an epsilon tie check; the reproduction is the Math.Round loop over 2.500000001 and 3.4999999999 in the issue. Start by reading that helper and checking whether the same logic is mirrored in other Fable targets. Done when both values round to 3 and Math.Round(x, digits) matches .NET behaviour, with a regression test added.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

Math.Round(double) calls a value a tie when its fraction is within 1e-8 of 0.5, so values near a half round the wrong way. That way 2.500000001 rounds down to 2 and 3.4999999999 rounds up to 4 under Fable 5.26.0, instead of 3 for both cases.

To reproduce this issue

open System
for x in [ 2.500000001; 3.4999999999 ] do
    printfn "%s" (string (Math.Round x))

fable-library-js’s Util.round reads the value through toFixed(8) and calls it a tie when the fraction is within 1e-8 of 0.5

const n = +(digits ? value * m : value).toFixed(8);
...
const r = (f > 0.5 - e && f < 0.5 + e) ? ((i % 2 === 0) ? i : i + 1) : Math.round(n);

Math.Round(double) works on the exact value and a tie is a fraction of exactly one half.

Suggested fix that would be exact.

const t = Math.trunc(x), f = Math.abs(x - t);
return f > 0.5 ? t + Math.sign(x) : f < 0.5 ? t : (t % 2 === 0 ? t : t + Math.sign(x));

For Math.Round(x, digits) the same applies after scaling by 10^digits, as .NET does.

Lenguaje dominante
F#
Estrellas
3.2k
Forks
335
Merge medio
19 h 39 min
PR fusionados (30 d)
158

Preparar el entorno

Abrir en Codespaces

Inicia el contenedor de desarrollo del proyecto en tu navegador, con tu propia cuenta de GitHub.

  • Sin Dockerfile ni archivo de Docker Compose
  • Sin plantilla de pull request
  • Sin guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de fable-compiler/Fable

Todos los issues de fable-compiler/Fable

Issues similares

Más issues de Compilers

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.