0

関数のPHP マニュアル ページの例 #2 は次のとおりです。dechex()

// The output below assumes a 32-bit platform.
// Note that the output is the same for all values.
echo dechex(-1)."\n";
echo dechex(PHP_INT_MAX * 2 + 1)."\n";
echo dechex(pow(2, 32) - 1)."\n";

上記の例では、次のように出力されます。

ffffffff
ffffffff
ffffffff

x64 システムでその動作を再現しようとしています:

echo dechex(-1)."\n";
echo dechex(PHP_INT_MAX * 2 + 1)."\n";
echo dechex(pow(2, 64) - 1)."\n";

私は期待している :

ffffffffffffffff
ffffffffffffffff
ffffffffffffffff

しかし、私は得る:

ffffffffffffffff
0
0

ここで何が起こっているのですか?

4

2 に答える 2

0

まず、PHPdechex関数には整数入力が必要であることに注意することが重要です。

64ビットシステムでは、PHPは64ビット整数をサポートしていません。

たとえばPHP_INT_MAX、64ビットシステムの一般的な例は次のとおりです。

 9223372036854775807

これは、受け入れることができる最大の整数(!)数でもありdechexます。

渡すと、整数に変換されpow(2, 64) - 1たfloat(1.844674407371E+19)は整数である0ためdechex、文字列を返します"0"

2^64を文字列として渡す場合も同様です"18446744073709551615"。これは整数に変換され、その整数値は922337203685477580764​​ビットシステム上にあります。したがって、dechexは文字列を返します"7fffffffffffffff"

したがって、これらの数値を処理する必要がある場合は、PHPの整数型を使用できないdechexため、この作業に適したツールではありません。代わりに、bcmathおよびgmp関数を使用して、探しているものを実現できます。

echo gmp_strval(bcadd(bcmul(2, PHP_INT_MAX), 1), 16), "\n";
echo gmp_strval(bcsub(bcpow(2, 64), 1), 16), "\n";
于 2013-03-08T07:43:51.340 に答える
0

float として格納できる最大の整数が pow(2,53)-1 であり、9007199254740991 であるという事実に関連して、64 ビット プラットフォームで dechex にバグがあると思われます。浮動小数点数を使用している可能性があり、浮動小数点システムの不正確さによって奇妙な結果が発生する可能性があるため、base_convert を使用した数値。同様のことが dehex でも発生している可能性があります。

PHP は dehex のパラメーターとして整数または浮動小数の数値を受け入れますが、浮動小数点数は実際には int の境界をオーバーフローする整数を表現するためのデバイスにすぎません。実際には、32 ビット プラットフォームで正常に実行されたコードは、以下のコメントが示すように、32 ビット プラットフォームの最大整数値を超える値を dehex に渡し、float を渡します。

<?php

echo "Max int: ",PHP_INT_MAX, "\n"; // Max int: 2147483647
$num = (PHP_INT_MAX * 2) + 1;
var_dump($num);   //                // float(4294967295)
echo dechex($num),"\n";            // ffffffff
echo dechex(-1);                   // ffffffff

bugs.php.net でバグ レポートを提出することをお勧めします。

于 2013-07-07T21:18:52.550 に答える