Skip to content

PDO Sqlite is truncating float #8510

Closed
Closed

Description

@mvorisek

Description

The following code:

<?php

$pdo = new PDO('sqlite::memory:');

$pdo->exec('CREATE TABLE "types" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "float" DOUBLE PRECISION)');

$pdo->exec('insert into "types" ("float") values (10)');

$pdo->exec('update types set float = 8.202343767574732');
$stored = $pdo->query('select float from types limit 1')->fetchColumn(0);
var_dump($stored);
var_dump(bin2hex(pack('e', $stored)));

$pdo->exec('update types set float = \'8.202343767574732\'');
$stored = $pdo->query('select float from types limit 1')->fetchColumn(0);
var_dump($stored);
var_dump(bin2hex(pack('e', $stored)));

Resulted in output with truncated float numbers, but I expected this output instead:

-string(16) "8.20234376757473"
+string(16) "8.202343767574732"
-string(16) "d790309a99672040"
+string(16) "d890309a99672040"
-string(16) "8.20234376757473"
+string(16) "8.202343767574732"
-string(16) "d790309a99672040"
+string(16) "d890309a99672040"

demo: https://3v4l.org/5Qtf8

it is solely related with PDO Sqlite, PDO Mysql, PDO MSSQL, PDO PostgreSQL and PDO Oracle provide correct result

since PHP 8.1, a float Sqlite datatype is returned as a php float type and the result is correct

PHP Version

PHP 8.0

Operating System

any

Activity

  1. cmb69 commented on May 8, 2022

    @cmb69
    Member

    since PHP 8.1, a float Sqlite datatype is returned as a php float type and the result is correct

    Is it? I mean this is about floating point numbers which are not (necessarily) exact.

    Anyway, we won't backport 438b025 to PHP-8.0.

  2. mvorisek commented on May 8, 2022

    @mvorisek
    ContributorAuthor

    Is it?

    yes, 64-bit IEEE 754 floating-point has specific precision

    Although Sqlite does guarantee only 15 significant digits precision, 438b025#diff-6f85d6c531f4d77a70ce04f8bfcec3adc6679a0cd10b44b301f4e1107a41090cR285 line should be backported and the float casted to string with full precision. This way, string type for BC would be kept, but full precision would be returned.

  3. mvorisek commented on Oct 28, 2026

    @mvorisek
    ContributorAuthor

    Good news! In SQLite v3.53.0 full precision is newly rendered:

    Improvements to floating-point ↔ text conversions.
    Rounding is now done by default to 17 significant digits, instead of 15, as was the case for all prior versions. The sqlite3_db_config(SQLITE_DBCONFIG_FP_DIGITS) API (item 6g above) can change this, if desired.

    source: https://www.sqlite.org/releaselog/3_53_0.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions