[PHP-users 28028] Re: 整数の下限
 Yasuo Ohgaki
 yohgaki @ ohgaki.net
 
 2006年 1月 4日 (水) 23:48:01 JST
 
 
 
大垣です。
SAISHO Kazuhiro wrote:
> オンラインマニュアルで学習中の税所です。
> いつもお世話になっております。
>> さて、内容的にFAQかと思いますが、
> うまく検索できませんでしたので質問させてください。
> 次の2行がどうしてなのかわかりません。
>> var_dump (-2147483647 - 1); # int(-2147483648)
> var_dump (-2147483648 ); # float(-2147483648)
>> 環境は、PHP 4.4.0 / FreeBSD 5.4-STABLE です。
> 宜しくお願い致します。
こう言った場合の動作が気になるのであればソースを見るのが
一番簡単です。以下のコードはPHP 5.1.1のコードですが他のバー
ジョンでもこの部分は変わらないと思います。
> var_dump (-2147483647 - 1); # int(-2147483648)
は
 if (op1->type == IS_LONG && op2->type == IS_LONG) {
 long lval = op1->value.lval - op2->value.lval;
 /* check for overflow by comparing sign bits */
 if ( (op1->value.lval & LONG_SIGN_MASK) != (op2->value.lval & LONG_SIGN_MASK)
 && (op1->value.lval & LONG_SIGN_MASK) != (lval & LONG_SIGN_MASK)) {
 result->value.dval = (double) op1->value.lval - (double) op2->value.lval;
 result->type = IS_DOUBLE;
 } else {
 result->value.lval = lval;
 result->type = IS_LONG;
 }
 return SUCCESS;
 }
となっているのでアンダーフローチェックに引っかからないです。
> var_dump (-2147483648 ); # float(-2147483648)
は
<ST_IN_SCRIPTING>{LNUM} {
 errno = 0;
 zendlval->value.lval = strtol(yytext, NULL, 0);
 if (errno == ERANGE) { /* overflow */
 zendlval->value.dval = zend_strtod(yytext, NULL);
 zendlval->type = IS_DOUBLE;
 return T_DNUMBER;
 } else {
 zendlval->type = IS_LONG;
 return T_LNUMBER;
 }
}
となっているのでERANGEがセットされているのでfloatになっているのだと思います。
お使いの環境では
strtol("-2147483648", NULL, 0)
でerrnoにERANGEが設定されるのだと思います。
-- 
Yasuo Ohgaki
 
 
PHP-users メーリングリストの案内