tursodatabase/turso

ROUND() uses banker's rounding instead of round-half-away-from-zero

Open

#5.748 aberto em 6 de mar. de 2026

Ver no GitHub
 (2 comments) (0 reactions) (0 assignees)Rust (1.001 forks)github user discovery
correctnessfloating-pointgood first issuescalar-functions

Métricas do repositório

Stars
 (19.103 stars)
Métricas de merge de PR
 (Métricas PR pendentes)

Description

Description

ROUND(x, d) uses banker's rounding (round half to even) instead of round-half-away-from-zero when the digit at the rounding boundary is exactly 5.

Reproducer

SELECT ROUND(2.25, 1);
-- Turso: 2.2 (rounds to even)
-- SQLite: 2.3 (rounds away from zero)

SELECT ROUND(2.35, 1);
-- Both: 2.4 (agrees because 4 is even)

SELECT ROUND(2.45, 1);
-- Both: 2.5 (agrees due to float representation)

Note: Many .X5 values produce the same result in both systems due to IEEE 754 float representation artifacts. The difference is visible when the exact 0.5 boundary is hit, e.g. 2.25 which is exactly representable in binary.

Per SQLite documentation: the round() function uses C library printf-style rounding, which is round-half-away-from-zero.

core/vdbe/value.rs:647 - When precision > 0, uses format!("{f:.precision$}") which relies on Rust's default banker's rounding. When precision == 0, it correctly uses f + 0.5 truncation.


This issue brought to you by Mikaël and Claude Code.

Guia do colaborador