[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 メーリングリストの案内