[PHP-users 7420] Re: 長い文字列の比較

Eita Morikawa php-users@php.gr.jp
Tue, 14 May 2002 10:18:49 +0900


森川です。

On Mon, 13 May 2002 23:51:54 +0900
HAYAKAWA Hitoshi <cz@hykw.tv> wrote:

> 早川仁です。
> 
> At Mon, 13 May 2002 23:19:29 +0900,
> Eita Morikawa wrote:
> 
> > 文字列の比較に'=='を用いた場合、最初の16文字のみしか対象に
> > してくれないようです(PHP4.1.2と4.0.5で確認しました)。
> > 
> > '==='を用いるかstrcmp()で比較を行うと、140文字程度の文字列
> > しか試していませんが、期待通りの結果が得られました。
> > 
> > スクリプトを書き直そうと思っているのですが、長い文字列を
> > 比較する場合のお勧めの方法をご教授いただけないでしょうか?
> > とりあえずやりたいのは、一致するか否かだけの判断です。
> 
> その == で比較した時の左辺値と右辺値はどうなっていますか?

これでテストしていました。

$str1 = "12345678901234563";
$str2 = "12345678901234564";

今日気付いたのですが、これだと違う結果になります。

$str3 = "1234567890123456a";
$str4 = "1234567890123456b";

($str1==$str2) は TRUEになります。
($str3==$str4) は FALSEになります。

gettypeで確認すると、$str1も$str2も'string'だったので、文字列と
して比較してくれてると思い込んでいたのですが、($str1==$str2)は
どうやら両辺を数値として評価して比較演算しているような気がします。

多分つぎのようなことがおきているのではないかと推測しています。
$str1,$str2はそれぞれinteger型として評価され、オーバーフローにより
最終的にfloat型の数値として比較。この時、$str1,$str2ともにfloatで
扱える最大値(マニュアルによればプラットフォーム依存、通常はおよそ
10進数で14桁の精度とのこと)を越えたため両者とも同じ値(最大値)と
なり、($str1==$str2)はTRUEとなる。

# PHP4.2.xではfloatval()というのがあるのですね。
# floatval($str1)とfloatval($str2)が同じ値になることを確認できれ
# ば良いのですが、手元に環境がないので確認はできていません。

マニュアルで関連する項目を下に抜粋しますが、上の仮説が正しいとして、
PHPはどういう場合に文字列を数値として評価するのでしょう?
私はarray_search()で、$str1のような文字列を扱ってはまりました。。。

<マニュアルからの抜粋>
(文字列)
 ・数値として文字列が評価された時、結果の値と型は次のように定義されます。 
 ・文字列は、'.'、'e'、'E' のどれかが含まれている場合は float、それ以外は整数として評価されます。 
(整数)
 ・integer型の範囲外の数を指定した場合、かわりに floatとして解釈されます。
  また、結果が integer型の範囲外の数となるような計算を行うと floatが代わりに返されます。 


> # まぁ binary safe なんで、普通 strcmp() を使いますね。

お勧めに従い、今回はstrcmp() を使いたいと思います。

-- 
Eita Morikawa <chanoma@parknet.co.jp>