我试图在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
是否有人知道解决此问题或解决方案的方法。
感谢。
答案 0 :(得分:2)
PHP函数hexdec()
也适用于32位。文档表示,当结果不适合32位时,它会生成float
个数字。
有趣的是0x3fffffffff
也存储为float
个数字。
罪魁祸首是按位运算符(&
),它似乎产生一个整数。将其结果转换为浮点并没有帮助,损坏已经完成。
此行为为documented:
两个操作数都将转换为整数,结果将是一个整数。
您可以尝试将输入字符串分成适合32位的片段并对它们使用按位运算符,然后使用加法和乘法生成最终值(如果不能适合32位,则加法和乘法将结果转换为float )。
这种情况的一个更简单的解决方案是将十六进制字符串转换为其编码的数字的二进制表示,提取每个组件所需的位,然后将值转换为十进制。在这种情况下不涉及位操作(转换除外,但这些操作似乎正常)。
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;
}