php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #67839 mysqli does not handle 4-byte floats correctly
Submitted: 2014-08-14 05:36 UTC Modified: 2014-08-15 23:52 UTC
From: keyur@php.net Assigned: keyur (profile)
Status: Closed Package: MySQLi related
PHP Version: 5.4.31 OS: Linux
Private report: No CVE-ID: None
 [2014-08-14 05:36 UTC] keyur@php.net
Description:
------------
mysqli does not handle 4-byte floats correctly. It casts it into a double which essentially increases the "error" in the IEEE-754 FP number.

Consider the following C code:
float a = 99.99f;
double b = (double) a;

The output will be:
a = 99.9899979
b = 99.989997863769531

b will never be printed as 99.99

Test script:
---------------
On a MySQL DB, run the following queries:

CREATE TABLE test(id INT PRIMARY KEY, fp4 FLOAT, fp8 DOUBLE) ENGINE = InnoDB;
INSERT INTO test(id, fp4, fp8) VALUES (1, 9.9999, 9.9999)

Now using mysqli, SELECT the one row out:
        if (!($stmt = mysqli_prepare($link, "SELECT id, fp4, fp8 FROM test"))) {
                die();
        }
        if (!mysqli_stmt_execute($stmt)) {
                die();
        }
        if (!($result = mysqli_stmt_get_result($stmt))) {
                die();
        }
        $data = mysqli_fetch_assoc($result);
        print $data['id'] . ": " . $data['fp4'] . ": " . $data['fp8'] . "\n";

Expected result:
----------------
It should be:
1: 9.9999: 9.9999

Actual result:
--------------
The output will be:
1: 9.9998998641968: 9.9999

Patches

Add a Patch

Pull Requests

Pull requests:

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2014-08-14 05:40 UTC] keyur_govande at yahoo dot com
The patch for this bug is here: https://gist.github.com/keyurdg/9c99da11848ac7589e66
 [2014-08-15 23:52 UTC] keyur@php.net
-Status: Open +Status: Closed -Assigned To: +Assigned To: keyur
 [2014-08-15 23:52 UTC] keyur@php.net
The fix for this bug has been committed.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.

 For Windows:

http://windows.php.net/snapshots/
 
Thank you for the report, and for helping us make PHP better.


 [2014-10-19 08:09 UTC] nikita at paymentwall dot com
There is an issue which occurs in the "else" condition in mysqlnd_ps_codec.c on line 224 https://github.com/php/php-src/commit/c044164a96553668cc6c4ae1eb32f18219308851#diff-244e2eb2c3973758baa5d722dc42e7c0

------------
PHP version: 5.4.34
OS: FreeBSD 10.0, FreeBSD 9.1
Compiled with clang, not GCC

------------

CREATE TABLE test_php_bug(id INT PRIMARY KEY, fp4 FLOAT(8,2), fp8 DOUBLE) ENGINE = InnoDB;
INSERT INTO test_php_bug(id, fp4, fp8) VALUES (1, 38.50, 38.50);

if (!($stmt = mysqli_prepare($link, "SELECT id, fp4, fp8 FROM test_php_bug WHERE id=1"))) {
       die();                                                                    
}
if (!mysqli_stmt_execute($stmt)) {
       die();
}
if (!($result = mysqli_stmt_get_result($stmt))) {
       die();
}
$data = mysqli_fetch_assoc($result);
print $data['id'] . ": " . $data['fp4'] . ": " . $data['fp8'] . "\n";

-------------

Actual result:
1: 38: 38.5
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Tue Mar 19 01:01:30 2024 UTC