I don't see this behavior.
My experiment:
- Look at the db with SQLiteSpy. Find a float custom column. Image is below.

- Change a value in calibre, in this case 9.01 becomes 9.02
- Look at the db again. The value has changed and there is no duplicated row.

What are you doing that is different?
I also note that the table has a UNIQUE constraint on the book_id, so the db itself should toss exceptions in the case you describe.
Code:
CREATE TABLE custom_column_16(
id INTEGER PRIMARY KEY AUTOINCREMENT,
book INTEGER,
value REAL NOT NULL ,
UNIQUE(book));
CREATE INDEX custom_column_16_idx ON custom_column_16 (book);
CREATE TRIGGER fkc_insert_custom_column_16
BEFORE INSERT ON custom_column_16
BEGIN
SELECT CASE
WHEN (SELECT id from books WHERE id=NEW.book) IS NULL
THEN RAISE(ABORT, 'Foreign key violation: book not in books')
END;
END;
CREATE TRIGGER fkc_update_custom_column_16
BEFORE UPDATE OF book ON custom_column_16
BEGIN
SELECT CASE
WHEN (SELECT id from books WHERE id=NEW.book) IS NULL
THEN RAISE(ABORT, 'Foreign key violation: book not in books')
END;
END;