スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

[PHP] 2進の数を比較すると異なる値が同じと判断されることがある

異なる2進数の数値を10進数に変換したらとうぜんながら違うと判定されるのに、2進数で比較したら同じだよといわれたでござるの巻。




等しくねえよ!

ソースは以下のような感じ。
説明書きの部分は省いてあります。


<?php
//10進数として値をセット
$a = bindec( "11110000111100001111000011110000" );
$b = bindec( "11110000111100001111000011110001" );
if( $a == $b ){
$result .= "等しい( ".$a." = ".$b." )";
}else{
$result .= "等しくない( ".$a." != ".$b." )";
}
//2進数に変換
$a_bin = decbin( $a );
$b_bin = decbin( $b );
if( $a_bin == $b_bin ){
$result .= "等しい( ".$a_bin." = ".$b_bin." )";
}else{
$result .= "等しくない( ".$a_bin." != ".$b_bin." )";
}
?>


なんでもともと異なる値が変換かけたら同じものとして判定されるの?
PHPが型とかもってないことが関係してるのかしら? 原因は謎。調べたらわかるのかもしれんけど。
とりあえず比較かけるときは10進数に変換しておいたほうがよかろうという自分へのメモ。

追記:
上記のソースで初めにセットする2進数としての値(実際セットされるときには文字列だけれど)が16桁のときまでは正常に判断できて、17桁を超えるとダメになることを確認。ビット処理でなんかいろいろあるんだろうか。
関連記事
スポンサーサイト

comment

管理者にだけメッセージを送る

No title

んー気になって調べてみたんですがdecbin関数は2進形式の「文字列」を返すんですよね。
ほいで、「数値っぽい文字列」同士の比較というのはどうも暗黙にfloatにキャストされるみたいで、それによる誤差が発生してるとか?

http://techblog.ecstudio.jp/tech-tips/php-string-compare.html

関数を介さず文字列リテラル同士で比較してみたんですが、

"11110000111100001"(1と0から成る17桁の文字列) と、
"11110000111100000"(同)

は確かにequalになりますね。

ほいで、一桁ずつ1を追加して

"111100001111000011"(1と0から成る18桁の文字列) と、
"111100001111000001"(同)

を比較するとnot equalだと言われました。
なので、単純に17桁以上だとダメってことでもないような気がしました。
なんか誤差っぽい挙動だなと。

そんなにきっちり調べたわけじゃないんで、的外れだったらすいません;

あれ

じゃあ内部で float としたときに何かが溢れてしまうのか。
ややこしいなあ。0.99999999999999999999と1は等しいみたいなもんか。
めったに進法のことなんか意識しないけれど、こんなときにコンピュータが0/1の機械だってことを思い知らされるなあ。

サンクスです。
検索フォーム
リンク
最新記事
最新コメント
カテゴリ
RSSリンクの表示
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。