使用PHP hexdec的大十六进制值

时间:2009-08-13 17:37:53

标签: php hex

我有一些大的HEX值,我想显示为常规数字,我使用hexdec()转换为float,我在PHP.net上找到一个函数将其转换为十进制,但它似乎达到了天花板,例如:

$h = 'D5CE3E462533364B';
$f = hexdec($h);
echo $f .' = '. Exp_to_dec($f);

输出:1.5406319846274E + 19 = 15406319846274000000

来自calc.exe = 15406319846273791563的结果

是否有另一种转换大十六进制值的方法?

8 个答案:

答案 0 :(得分:22)

正如hexdec manual page所说:

  

该功能现在可以转换值   这对平台来说很重要   整数类型,它将返回值   在那种情况下反而浮动。

如果你想获得某种大整数(不是浮点数),你需要将它存储在一个字符串中。使用BC Math函数可以实现这一点。

例如,如果你查看hexdec手册页的评论,你会发现this note

如果你稍微调整一下这个功能,为了避免通知,你会得到:

function bchexdec($hex)
{
    $dec = 0;
    $len = strlen($hex);
    for ($i = 1; $i <= $len; $i++) {
        $dec = bcadd($dec, bcmul(strval(hexdec($hex[$i - 1])), bcpow('16', strval($len - $i))));
    }
    return $dec;
}

(此功能已从我链接到的备注中复制过来;只有一点适合我)

在你的号码上使用它:

$h = 'D5CE3E462533364B';
$f = bchexdec($h);
var_dump($f);

输出将是:

string '15406319846273791563' (length=20)

所以,不是那种大浮子;你似乎对你的期望似乎很好:

  

来自calc.exe =的结果   15406319846273791563


希望这有帮助;-)
而且,是的,有关PHP文档的用户注释有时是真正的金矿; - )

答案 1 :(得分:4)

当结果太大而无法表示为int时,

hexdec()从int切换到float。如果你想要任意长的值,你可能需要推出自己的转换函数来将十六进制字符串更改为GMP integer

function gmp_hexdec($n) {
  $gmp = gmp_init(0);
  $mult = gmp_init(1);
  for ($i=strlen($n)-1;$i>=0;$i--,$mult=gmp_mul($mult, 16)) {
    $gmp = gmp_add($gmp, gmp_mul($mult, hexdec($n[$i])));
  }
  return $gmp;
}

print gmp_strval(gmp_hexdec("D5CE3E462533364B"));

Output: 15406319846273791563

答案 2 :(得分:3)

1.5406319846274E + 19是您号码的有限代表。您可以使用printf()

获得更完整的一个
printf("%u\n", hexdec($h));

...将输出“15406319846273792000”。 PHP使用浮点数来表示这么大的数字,所以你可能会失去一些精确度。如果必须使用任意精度数字,可以尝试bcmath extension。通过将十六进制分成两个32位字(在大多数系统上应该是安全的),您应该能够获得更高的精度。例如:

$f = bcadd(bcmul(hexdec(substr($h, 0, -8)), 0x100000000), hexdec(substr($h, 8)));

...将$ f设置为15406319846273791563。

答案 3 :(得分:3)

将HEX转换为DEC很容易..但是,重建十六进制数字非常困难。 尝试使用base_convert ..

$hexadecimal = base_convert(2826896153644826, 10, 16);
// result: a0b0c0d0e0f1a

答案 4 :(得分:2)

$num = gmp_init( '0xD5CE3E462533364B' ); // way to input a number in gmp
echo gmp_strval($num, 10); // display value in decimal

这是要使用的模块。将其转换为函数,然后使用您的数字。

注意:将这些十六进制数字作为字符串提供:

$num = "0x348726837469972346"; // set variable
$gmpnum = gmp_init("$num"); // gmp number format
echo gmp_strval($gmpnum, 10); // convert to decimal and print out

答案 5 :(得分:2)

在MySQL数据库中存储64位密钥时遇到此问题。我能够使用一些二元运算符完美地转换为64位有符号整数(PHP限制):(此代码比bchexdec函数快16倍,结果变量平均使用一半的内存)。

function x64toSignedInt($k){
    $left = hexdec(substr($k,0,8));
    $right = hexdec(substr($k,8,8));
    return (int) ($left << 32) | $right;
}

MySQL签名的BIGINT数据类型通常与索引或存储很匹配。 HEX(列)是一种在SQL查询中将其转换回HEX以便在其他地方使用的简单方法。

答案 6 :(得分:0)

  

签出此简单方法

function bc_hexdec($input)
{
    $output = '0';

    if (preg_match('/^(0x)?(?P<hex>[a-f0-9]+)$/i', $input, $matches))
        foreach (str_split(strrev($matches['hex'])) as $index => $hex)
            $output = bcadd($output, bcmul(strval(hexdec($hex)), bcpow('16', strval($index))));

    return $output;
}

答案 7 :(得分:-1)

intval(var, base)照顾它吗?

来自PHP Manual