Skip to content
Astera Technology

Why does a negative offset enter the wrong unit bucket?

Distinguish truncation toward zero from a lower interval boundary.

Download complete case notes and answer keys ↓

Prepare the report input

Original bucket k means k≤value<k+1. CAST to INTEGER truncates toward zero, so −1.2 becomes −1 instead of required −2. Subtract one from the truncated integer only when the original value is below it. Values here are small finite offsets.

Every record and report rule below is original and fictional. Reproduce the setup in a fresh SQLite test database; input previews include every table in this small fixture.

Synthetic input: offsets
idvalue
A-1.2
B1.2
C-1
Download editable CSV ↓
Complete CREATE and INSERT fixture
CREATE TABLE offsets(id TEXT PRIMARY KEY,value REAL NOT NULL); INSERT INTO offsets VALUES('A',-1.2),('B',1.2),('C',-1.0);

Compare misleading and corrected results

Misleading SELECT: reproduce the defect
SELECT id,CAST(value AS INTEGER) AS bucket FROM offsets ORDER BY id;
Literal misleading result
idbucket
A-1
B1
C-1
Download editable CSV ↓
Corrected SELECT
SELECT id,CAST(value AS INTEGER)-CASE WHEN value<CAST(value AS INTEGER) THEN 1 ELSE 0 END AS bucket FROM offsets ORDER BY id;
Literal corrected result
idbucket
A-2
B1
C-1
Download editable CSV ↓

−1.2 belongs in [−2,−1), 1.2 in [1,2), and exact −1 stays in [−1,0). The correction preserves exact integer boundaries.

Check a fresh boundary case

Add zero; its bucket is zero rather than minus one.

Recreate the original setup in another fresh database, then apply the change and corrected query below. For an empty result, the table displays a labelled empty-result marker rather than a data record.

Boundary change and corrected query
INSERT INTO offsets VALUES('D',0);
SELECT id,CAST(value AS INTEGER)-CASE WHEN value<CAST(value AS INTEGER) THEN 1 ELSE 0 END AS bucket FROM offsets ORDER BY id;
Literal boundary result
idbucket
A-2
B1
C-1
D0
Download editable CSV ↓

Why is exact −1 not decremented again?

Show the worked answer

It equals its truncated integer, so value<CAST(value AS INTEGER) is false. Only a negative fractional remainder crosses to the lower bucket.

Related resources