You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
floor division truncates toward zero on duckdb (and 0//0 gives 0 on pandas) while every other backend floors #3984
// (floor division) truncates toward zero on duckdb but floors everywhere else, so the same expression returns different numbers for negative operands.
two divergences in one operator: duckdb truncates instead of flooring, and the pandas backend returns 0 for 0 // 0 (numpy semantics) where the rest return null.
this is the sibling of the floor-modulus work in #3929: % was floor-corrected across backends, but // on duckdb still follows the engine's native // which truncates. src/narwhals/_sql/expr.py maps floordiv straight through with only a divide-by-zero guard (_when(other != 0, ...)).
since duckdb's mod already returns the floor-consistent remainder (verified: -7 % 2 = 1, matching polars), the identity floor_div(a, b) = trunc_div(a - floor_mod(a, b), b) should give exact floor semantics without float round-trips: -7 - 1 = -8, trunc(-8 / 2) = -4.
expected behavior
duckdb // should floor like every other backend (and like % already does post-#3929).
for reference, ibis normalizes this exact case by compiling floor division differently for duckdb: their // returns -4 where raw duckdb // returns -3, might be worth a look at how they emit it
the pandas 0//0 == 0 half lives in a separate site (pandas-like backend). happy to run any patch through the cross-backend grid used for the original report
for reference, ibis normalizes this exact case by compiling floor division differently for duckdb: their // returns -4 where raw duckdb // returns -3, might be worth a look at how they emit it
the pandas 0//0 == 0 half lives in a separate site (pandas-like backend). happy to run any patch through the cross-backend grid used for the original report
Activity
ReguiguiMohamed commentedon Sep 27, 2026
I've started working on this. I'll link a PR.
ptimizeroracle commentedon Sep 27, 2026
nice, thanks
two things that may help:
floor_modin_utils.py(landed with fix: align__mod__and__rmod__behavior with negative operands across backends #3929), so the duckdb/sql side can reuse it for the correction term: floor_div(a, b) = (a - floor_mod(a, b)) / b, with the existing truncating division doing the rest//returns -4 where raw duckdb//returns -3, might be worth a look at how they emit itthe pandas
0//0 == 0half lives in a separate site (pandas-like backend). happy to run any patch through the cross-backend grid used for the original reportReguiguiMohamed commentedon Sep 27, 2026
thanks! PR is up in #3994
I tried the floor_mod route first but
(a % b) + boverflows near int64 max, e.g.10 // (2**63-1), so the fix corrects the truncated quotient instead.ibis emits
FLOOR(a / b)which goes through float64, so it loses precision on big ints:(2**62+1) // -3gives ...216 instead of ...302.would be great if you ran it through your grid