[PHP-users 28032] Re: 整数の下限
SAISHO Kazuhiro
ml @ saisho.info
2006年 1月 5日 (木) 16:48:48 JST
税所です。
ご返信ありがとうございます。
[PHP-users 28028]
> 大垣です。
> こう言った場合の動作が気になるのであればソースを見るのが
> 一番簡単です。以下のコードは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が設定されるのだと思います。
前者は zend_operators.c に、後者は zend_language_scanner.l に、
それぞれ記述されていますね。
でも私がそこに辿り着けたのは、大垣さんからご提示戴いたコードを
キーワードにしてファイルを検索したからにすぎません。
初めに質問させて戴いたような動作が気になるからといって、
どのソースを見ればいいかということは決して「簡単」ではないと
思いますが、如何でしょうか?
どうすればこのファイルのこのコードに辿り着くことができたのでしょうか?
ところで、前者の
> if ( (op1->value.lval & LONG_SIGN_MASK)
> != (op2->value.lval & LONG_SIGN_MASK)
> && (op1->value.lval & LONG_SIGN_MASK)
> != (lval & LONG_SIGN_MASK)) {
この部分は、バージョン4.4.1では、
if ( (op1->value.lval & LONG_MIN)
!= (op2->value.lval & LONG_MIN)
&& (op1->value.lval & LONG_MIN)
!= (lval & LONG_MIN)) {
このようになっていました。
つまり、
5.1.1 では LONG_SIGN_MASK
4.4.1 では LONG_MIN
になっています。
#define LONG_SIGN_MASK (1L << (8*sizeof(long)-1))
#define LONG_MIN (- LONG_MAX - 1)
とのことのようですので、
sizeof(long) の返り値が「4」であればしっくりいくような気がしますが、
この「long」とはいったい何でしょうか?
検索しようにも「long」という単語はたくさんありすぎて
絞り込むことができません。ご教授戴けましたら幸いです。
宜しくお願い致します。
--
税所 一弘 <ml @ saisho.info>
PHP-users メーリングリストの案内