9

誰かが私のために片付けてくれるかどうか疑問に思っていた奇妙な行動がありました。

見てみな

$hex = 0x80008000;

print_r(decbin(intval($hex)) . '<br/>');
print_r(decbin($hex));

出力

10000000000000001000000000000000
10000000000000001000000000000000

予想通り。

しかし

$hex = 0x80008000;

print_r(decbin(~intval($hex)) . '<br/>');
print_r(decbin(~$hex));

出力

1111111111111110111111111111111
1111111111111111111111111111111

$hexがネゲートされたときに中間ビットが切り替わらないのはなぜですか?

4

2 に答える 2

0

ここで私自身の質問に挑戦します。

はい、これは 32 ビット / 64 ビットの違いです。

32 ビット システムでは、float 型は、必要な 64 ビットを取得するために 2 つのメモリ空間を占有する必要があります。PHP は倍精度を使用します ( http://en.wikipedia.org/wiki/Floating_point#IEEE_754:_floating_point_in_modern_computersを参照) 。

$hex は float 型に評価されます。Intval および decbin 関数は、これを int 型に変換します (上記の 1 番目の例)。

2 番目の例では、decbin を使用する前に非ビット演算子を使用しています。これは、最初に 2 メモリ空間の倍精度 float のビットを反転し、次に int 秒に変換します。私たちが期待していたものとは違うものを私たちに与えてくれます。

実際、次のように intval() の中に否定を入れると:

$hex = 0x80008000;

print_r(decbin(intval(~$hex)) . '<br/>');
print_r(decbin(~$hex));

我々が得る

1111111111111111111111111111111
1111111111111111111111111111111

出力として。

私はまだこれを数学で証明するのに十分ではありません (これは、この記事http://en.wikipedia.org/wiki/Double_precisionの助けを借りて理解できます)。でも、後で時間ができたときかもしれません-_-

このような異常を理解してバグと呼ばないようにするために、コンピューターで数値がどのように表現されるかを学ぶことは非常に重要だと思います。

于 2012-03-11T20:09:49.640 に答える
-1

おそらくこれに該当するケース:

phpビット演算子ページからhttp://us3.php.net/manual/en/language.operators.bitwise.php

NOTまたは補数演算子(〜)と負の2進数は、混乱を招く可能性があります。

式〜x = -x --1を使用するため、〜2 = -3 10進数のビット単位の補数は、数値から1を引いたものの否定です。

注:以下の例ではここで4ビットを使用していますが、実際にはPHPは32ビットを使用しています。

負の10進数(つまり:-3)を2進数に変換するには3つの手順が必要です:1)正の10進数を2進数に変換する(つまり:3 = 0011)2)ビットを反転します(つまり:0011は1100になります)3) 1を追加します(つまり、1100 + 0001 = 1101)

1101=-3とはどういうことか疑問に思われるかもしれません。PHPは、メソッド「2の補数」を使用して、負の2進数をレンダリングします。左端のビットが1の場合、2進数は負であり、ビットを反転して1を加算します。0の場合、正であり、何もする必要はありません。したがって、0010は正の2になります。1101の場合は負であり、ビットを反転して0010を取得します。1を加算すると、-3に等しい0011が取得されます。

于 2012-03-08T20:25:28.420 に答える