ID:               47805
 Comment by:       simon at stienen dot name
 Reported By:      vivekanandan8 at yahoo dot com
 Status:           Open
 Bug Type:         Scripting Engine problem
 Operating System: Debian
 PHP Version:      5.2CVS-2009-03-27 (snap)
 New Comment:

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


Previous Comments:
------------------------------------------------------------------------

[2009-03-27 11:06:06] 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)


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


-- 
Edit this bug report at http://bugs.php.net/?id=47805&edit=1

Reply via email to