php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #62465 intval of floats
Submitted: 2012-07-02 16:30 UTC Modified: 2012-07-02 19:02 UTC
From: fabrizio at queensboro dot com Assigned:
Status: Not a bug Package: *General Issues
PHP Version: 5.4.4 OS: FreeBSD 9.0-RELEASE - amd64
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: fabrizio at queensboro dot com
New email:
PHP Version: OS:

 

 [2012-07-02 16:30 UTC] fabrizio at queensboro dot com
Description:
------------
Converting from a float to an integer doesn't always return the correct values.

Try this code:
<?php
$grand_total = 8.9500;
$amount = intval($grand_total*100);                                  
var_dump($amount, $grand_total*100, (int)($grand_total*100));        
?>

This will output:
int(894)
float(895)
int(894)

when I would expect:

int(895)
float(895)
int(895)

Test script:
---------------
<?php
$grand_total = 8.9500;
$amount = intval($grand_total*100);                                  
var_dump($amount, $grand_total*100, (int)($grand_total*100));        
?>

Expected result:
----------------
int(895)
float(895)
int(895)

Actual result:
--------------
int(894)
float(895)
int(894)

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2012-07-02 16:47 UTC] rasmus@php.net
Floating point values have a limited precision. Hence a value might 
not have the same string representation after any processing. That also
includes writing a floating point value in your script and directly 
printing it without any mathematical operations.

If you would like to know more about "floats" and what IEEE
754 is, read this:
http://www.floating-point-gui.de/

Thank you for your interest in PHP.

You are going to want to round() and not truncate here.
 [2012-07-02 16:47 UTC] rasmus@php.net
-Status: Open +Status: Not a bug
 [2012-07-02 18:23 UTC] fabrizio at queensboro dot com
Very interesting.
Thank you for your link, I always assumed that this was an issue for old 
languages and that new ones would have corrected the conversion to integer using 
some sort of checking against the "to_string" (I am saying this without knowing 
what it takes or what the code looks like).

As you can see here, the code knows that the value is a float(895), without 
decimals, so the integer should be the same, else I would expect an output like 
float(894.99999999...) during the var_dump.

<?php
$grand_total = '8.9500';
var_dump(                                                            
        $grand_total,                                                
        $grand_total*100,                                            
        round($grand_total*100),                                     
        intval($grand_total*100)                                     
);                                                                   
?>


string(6) "8.9500"
float(895)
float(895)
int(894)
 [2012-07-02 18:23 UTC] fabrizio at queensboro dot com
correct misspelled OS
 [2012-07-02 18:23 UTC] fabrizio at queensboro dot com
-Operating System: reeBSD 9.0-RELEASE - amd64 +Operating System: FreeBSD 9.0-RELEASE - amd64
 [2012-07-02 18:48 UTC] rasmus@php.net
Well, that is just because your output precision is set low enough so when the 
value is printed it prints as 895. Try adding this to the top of your test 
script:

ini_set('precision',32);

And no, this isn't a modern language vs. old language thing. 

For example, in Python:
Python 2.7.3 (default, Apr 20 2012, 22:39:59) 
>>> a=8.9500
>>> print a*100
895.0
>>> from math import floor
>>> print floor(a*100)
894.0

The way to fix this is to use arbitrary precision math routines and every 
scripting language, including PHP (see gmp, bcmath) provides those, but they are 
so much slower than the cpu-provided floating routines that it is hard to 
justify.
 [2012-07-02 18:54 UTC] fabrizio at queensboro dot com
I never stop learning!!

Thank you very much !
 [2012-07-02 18:57 UTC] fabrizio at queensboro dot com
Wouldn't make sense to have the conversion to INT work based on the precision ?

precision32:
 - intval(float(894.99999999999988631316227838397)) = 894
precision 14:
 - intval(float(894.99999999999988631316227838397)) = 895
 [2012-07-02 19:02 UTC] rasmus@php.net
That's exactly what round is for. You pass the rounding precision you want as an 
argument.
 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Sun Jul 13 11:01:33 2025 UTC