tursodatabase/turso

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

Chiusa

#5748 aperta il 6 mar 2026

 (2 commenti) (0 reazioni) (0 assegnatari)Rust (1001 fork)github user discovery
correctnessfloating-pointgood first issuescalar-functions

Metriche repository

Star
 (19.103 stelle)
Metriche merge PR
 (Merge medio 2g 11h) (147 PR mergiate in 30 g)

Descrizione

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.

Guida contributor