如何使用 32 位机器打印 PHP 中的 40 位数字
How to print a 40 bit number in PHP using a 32 bit machine
我正在尝试在 php 中打印一个 40 位数。但是当使用 Windows 机器时,它只允许 32 位整数,这导致我的代码回显错误的结果。以下代码示例:
function decoded_microchip_id($coded_string) {
$manufacturer = substr($coded_string, 0, 3);
$manufacturer = hexdec($manufacturer);
$manufacturer = $manufacturer / 4;
$device_id = substr($coded_string, 2, 11);
$device_id = hexdec($device_id);
$device_id = $device_id & 0x3fffffffff;
echo $manufacturer.'.'.$device_id;
};
decoded_microchip_id('f58e29a43c67');
以上代码的正确输出是:982.60828171367
但在我的 32 位 Windows 环境中,我得到:982.698629223
在各种 PHP 沙箱中测试代码时,输出也不同。
这里是一个沙箱环境的例子,给出了正确的输出:
http://sandbox.onlinephpfunctions.com/code/83cc28fd5314557e7a9d86d8061e1c8dfae4d1b7
下面是一个产生错误输出的环境示例:
http://codepad.org/m2ygOgC6
有没有人知道解决这个问题的方法或解决方案。
谢谢。
PHP 函数 hexdec()
在 32 位上也能正常工作。文档说当结果不适合 32 位时它会生成 float
数字。
有趣的是 0x3fffffffff
也存储为 float
数字。
罪魁祸首是似乎产生整数的按位运算符 (&
)。将其结果转换为浮点数没有帮助,损害已经造成。
这种行为是documented:
both operands will be converted to integers and the result will be an integer.
一个潜在的解决方案
您可以尝试将输入字符串拆分为适合 32 位的片段,并对它们使用按位运算符,然后使用加法和乘法生成最终值(加法和乘法如果不能放入,则将结果转换为浮点数32 位)。
一个具体的解决方案
针对这种情况的一个更简单的解决方案是将十六进制字符串转换为它编码的数字的二进制表示形式,提取每个组件所需的位,然后将值转换为十进制。在这种情况下不涉及任何位操作(转换除外,但那些似乎工作正常)。
function decoded_microchip_id($coded_string)
{
// Convert to binary
$bin = base_convert($coded_string, 16, 2);
// Split to 10/38 bits
$manufacturer = substr($bin, 0, 10);
$device_id = substr($bin, 10, 38);
// Convert to decimal
$manufacturer = bindec($manufacturer);
$device_id = bindec($device_id);
// Put pieces back
return $manufacturer.'.'.$device_id;
}
我正在尝试在 php 中打印一个 40 位数。但是当使用 Windows 机器时,它只允许 32 位整数,这导致我的代码回显错误的结果。以下代码示例:
function decoded_microchip_id($coded_string) {
$manufacturer = substr($coded_string, 0, 3);
$manufacturer = hexdec($manufacturer);
$manufacturer = $manufacturer / 4;
$device_id = substr($coded_string, 2, 11);
$device_id = hexdec($device_id);
$device_id = $device_id & 0x3fffffffff;
echo $manufacturer.'.'.$device_id;
};
decoded_microchip_id('f58e29a43c67');
以上代码的正确输出是:982.60828171367
但在我的 32 位 Windows 环境中,我得到:982.698629223
在各种 PHP 沙箱中测试代码时,输出也不同。
这里是一个沙箱环境的例子,给出了正确的输出: http://sandbox.onlinephpfunctions.com/code/83cc28fd5314557e7a9d86d8061e1c8dfae4d1b7
下面是一个产生错误输出的环境示例: http://codepad.org/m2ygOgC6
有没有人知道解决这个问题的方法或解决方案。
谢谢。
PHP 函数 hexdec()
在 32 位上也能正常工作。文档说当结果不适合 32 位时它会生成 float
数字。
有趣的是 0x3fffffffff
也存储为 float
数字。
罪魁祸首是似乎产生整数的按位运算符 (&
)。将其结果转换为浮点数没有帮助,损害已经造成。
这种行为是documented:
both operands will be converted to integers and the result will be an integer.
一个潜在的解决方案
您可以尝试将输入字符串拆分为适合 32 位的片段,并对它们使用按位运算符,然后使用加法和乘法生成最终值(加法和乘法如果不能放入,则将结果转换为浮点数32 位)。
一个具体的解决方案
针对这种情况的一个更简单的解决方案是将十六进制字符串转换为它编码的数字的二进制表示形式,提取每个组件所需的位,然后将值转换为十进制。在这种情况下不涉及任何位操作(转换除外,但那些似乎工作正常)。
function decoded_microchip_id($coded_string)
{
// Convert to binary
$bin = base_convert($coded_string, 16, 2);
// Split to 10/38 bits
$manufacturer = substr($bin, 0, 10);
$device_id = substr($bin, 10, 38);
// Convert to decimal
$manufacturer = bindec($manufacturer);
$device_id = bindec($device_id);
// Put pieces back
return $manufacturer.'.'.$device_id;
}