我在Mac和Linux上运行的PHP代码中遇到了不同的输出。
我有2台运行以下代码的服务器:
$ltt = ((ord($str[7]) << 24) | (ord($str[8]) << 16) | (ord($str[9]) << 8) | (ord($str[10]))) / 1000000;
即使ord(str[ ])
输出也相同:
[7] = 254
[8] = 26
[9] = 22
[10] = 216
但是,在运行php 5.3.6的MAMP堆栈(Mac)上,如果$ ltt最初应该是负数,则返回4263.12265
(不正确)。
在运行相同php版本的LAMP堆栈(Ubuntu)上,它将返回确切的负值-31.84465
。
只有负数才会发生..
更新Addl。的信息:
þØçï_Kstring(25) "þØçï_K"
000e1b00000000fe1a16d806e707ef0000045f0000004b0000
简化函数仅包含数字输入,输出仍然不同:
$ltt = (254 << 24 | 26 << 16 | 22 << 8 | 216)/ 1000000;
MAMP上的 4263.12265
和LAMP上的-31.84465
答案 0 :(得分:4)
这是一个32对64位的问题。
因为你最重要的字节是&gt; 127,在32位平台上,由于整数溢出,这被解释为负值 - 设置最高有效位。在64位平台上,它不是。
解决方案是使用pack()
和unpack()
,以便您可以指定应该对整数进行签名。 编辑 修正了此代码示例请参阅编辑2
$packed = pack('C*', ord($str[7]), ord($str[8]), ord($str[9]), ord($str[10]));
$unpacked = unpack('l', $packed);
$lat = current($unpacked);
...但是你也应该意识到这不适用于小端架构,因为字节顺序是错误的。你可以简单地颠倒打包字节的顺序来解决这个问题,但我只是试图围绕一个无处不在的解决方案。
编辑2
好吧,我花了一些时间来解决这个问题,但最后我们到了那里:您需要做的是,如果设置了最高有效位,或者结果是一个数字,其中最低有效32位未设置,但其余为。因此,以下适用于32位和64位:
<?php
// The input bytes as ints
$bytes = array(254, 26, 22, 216);
// The operand to OR with at the end
$op = $bytes[0] & 0x80 ? (~0 << 16) << 16 : 0;
// Do the bitwise thang
$lat = (($bytes[0] << 24) | ($bytes[1] << 16) | ($bytes[2] << 8) | $bytes[3]) | $op;
// Convert to float for latitude
$lat /= 1000000;
echo $lat;