php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #47805 integer overflows it is converted to double but it is not done in vice versa.
Submitted: 2009-03-27 11:06 UTC Modified: 2009-06-02 08:36 UTC
From: vivekanandan8 at yahoo dot com Assigned:
Status: Not a bug Package: Scripting Engine problem
PHP Version: 5.2CVS-2009-03-27 (snap) OS: Debian
Private report: No CVE-ID: None
 [2009-03-27 11:06 UTC] vivekanandan8 at yahoo dot com
Description:
------------
when the integer overflows it is converted to double but it is not done in vice versa.
Hence i fell:
it is not done from double to long.
Hence in the function increment_function(zend_operators.c)
we have to add the validation as follows 
case IS_DOUBLE:  
 if(op1->value.dval == LONG_MIN) {   
  op1->value.lval = (long) op1->value.dval+1;
  op1->type = IS_LONG; 
 }else{
   op1->value.dval = op1->value.dval + 1;
}

Reproduce code:
---------------
<?

$vValue = -2147483647;
var_dump($vValue); //output: int(-2147483647) 
$vValue--;
var_dump($vValue); //output: float(-2147483648) 
$vValue--;
var_dump($vValue); //output: float(-2147483649) 
$vValue++;
var_dump($vValue);//output: float(-2147483648) 
$vValue++;
var_dump($vValue);//output: float(-2147483647)
?>

Expected result:
----------------
int(-2147483647) int(-2147483648) float(-2147483649) int(-2147483648) int(-2147483647)

Actual result:
--------------
int(-2147483647) int(-2147483648) float(-2147483649) float(-2147483648) float(-2147483647)

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2009-04-30 17:51 UTC] simon at stienen dot name
Well, the goal is to preserve the current type if you do arithmetic, that's why $int++ will yield an int and $float++ will yield a float.

While floats can just shift into a higher magnitude if their value becomes too large, at the cost of a more rough granularity, integers can not. In the underlying language, C, the integer would just overflow: With the two-complement 32 bit integer you probably have, if x has the maximal value of 2147483647, after x++ it would contain the value -2147483648, which is the lowest value it can hold.

While this behaviour is logical and even searched for in many cases of low level coding, in web based apps it usually is not. As a result it was decided that $int++ should always result in the next higher number - but since the underlying integer in C could not store this value, the type is automatically changed to float.

However, the information that this variable resulted from an integer is lost in that process. It would probably be too much work to add a flag to document their integer origin to all these floats (otherwise existing scripts doing type checking using is_float might suddenly break) - but that's not even the point, as due to the granularity of floating point numbers this is a one way street anyway. Additionally you would have to check on each ++ or -- of a floating point number whether the result is a whole number AND in the range of integer values.

After all these bad news, there's some light on the horizon as well: With 64 bit operating systems coming up, integers will soon cover the whopping range of -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 and if that does not suffice, or if you need it right now and can't switch to a 64 bit system, you can still use the BC extension: http://php.net/ref.bc
 [2009-06-02 08:36 UTC] jani@php.net
Thank you for taking the time to write to us, but this is not
a bug. Please double-check the documentation available at
http://www.php.net/manual/ and the instructions on how to report
a bug at http://bugs.php.net/how-to-report.php


 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Tue Jul 15 23:01:33 2025 UTC