tursodatabase/turso

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

Open

#5,748 opened on 2026年3月6日

GitHub で見る
 (2 comments) (0 reactions) (0 assignees)Rust (1,001 forks)github user discovery
correctnessfloating-pointgood first issuescalar-functions

Repository metrics

Stars
 (19,103 stars)
PR merge metrics
 (PR metrics pending)

説明

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.

コントリビューターガイド