为什么PHP使用Zend_Amf将数字16转换为浮点(6.1026988574311E_320)

为什么PHP使用Zend_Amf将数字16转换为浮点(6.1026988574311E_320),php,floating-point,integer,Php,Floating Point,Integer,Zend_Amf规范声明从flash返回的数字类型将映射到PHP中的浮点。好的但是为什么数字16返回为6.1026988574311E_320?PHP版本是在OSX上运行的5.2.9 我曾尝试在PHP中强制转换为整数(上面的值被四舍五入为0),也尝试过使用int(16)从Actionscript强制转换为整数——后者是NULL。如何确保Flash通过AMF返回一个整数,并且PHP可以处理它?我不完全知道在您的情况下出现了什么问题,但我想我可以部分说明代码中发生了什么。我运行了以下快速破解来测试一

Zend_Amf规范声明从flash返回的数字类型将映射到PHP中的浮点。好的但是为什么数字16返回为6.1026988574311E_320?PHP版本是在OSX上运行的5.2.9


我曾尝试在PHP中强制转换为整数(上面的值被四舍五入为0),也尝试过使用int(16)从Actionscript强制转换为整数——后者是NULL。如何确保Flash通过AMF返回一个整数,并且PHP可以处理它?

我不完全知道在您的情况下出现了什么问题,但我想我可以部分说明代码中发生了什么。我运行了以下快速破解来测试一个理论:

void hexdump_double(double dbl) { assert(8 == sizeof(dbl)); printf("double: %02X %02X %02X %02X %02X %02X %02X %02X (%lg)\n", ((char *)&(dbl))[0], ((char *)&(dbl))[1], ((char *)&(dbl))[2], ((char *)&(dbl))[3], ((char *)&(dbl))[4], ((char *)&(dbl))[5], ((char *)&(dbl))[6], ((char *)&(dbl))[7], dbl); } int main() { hexdump_double(6.1026988574311E-320); } void hexdump_double(双dbl) { 断言(8==sizeof(dbl)); printf(“双精度:%02X%02X%02X%02X%02X%02X%02X%02X(%lg)\n”, ((char*)和(dbl))[0], ((char*)和(dbl))[1], ((char*)和(dbl))[2], ((char*)和(dbl))[3], ((char*)和(dbl))[4], ((char*)和(dbl))[5], ((char*)和(dbl))[6], ((char*)和(dbl))[7], dbl); } int main() { hexdump_double(6.1026988574311E-320); } 产生一些令人兴奋的输出:

double:40 30 00(6.1027e-320)

正如您所看到的,这个小浮点数不是任何随机的位模式。然而,它看起来也与“16”无关

Zend_Amf文档说明ActionScript数字类型以PHP浮点形式返回,这意味着Adobe记录的
类编号。这并不意味着任何“数字”都将作为双精度传递

值小于2^29的int将以整数类型在AMF中传输,我假设Zend_AMF将以整数类型返回


如何从ActionScript传输AMF对象?转储正在发送的字节是否可行?

您遇到了一个典型的endian问题。看起来Zend或flash都在用这个双精度的endianness做错误的事情。这是一个打印双精度(及其十六进制值)的程序。然后,它反转端点并再次打印

#include <stdio.h>
#include <stdint.h>

int main(void)
{
  double d = 16;
  uint32_t *i = (uint32_t *)(&d);
  uint8_t *c = (uint8_t *)(&d);
  size_t j;

  printf("%08x %08x %lg\n", i[1], i[0], d);

  for(j = 0; j < sizeof(double) / 2; j++)
  {
        uint8_t tmp;

        tmp = c[j];
        c[j] = c[sizeof(double) - j - 1];
        c[sizeof(double) - j - 1] = tmp;
    }

  printf("%08x %08x %lg\n", i[1], i[0], d);

  return 0;
}
您是否正在PPC Mac(big endian)上运行此功能?似乎您的一个工具在您的体系结构上做的事情不正确。向供应商提交一个bug


作为一种破解方法,我建议将您的数字转换为字符串,然后在另一端将其转换回双精度。

您使用的Zend Framework的哪个版本?1.9。更新到最新版本也没什么区别。它运行在PPC mac上,是的,但它也发生在Windows计算机上。我不确定确切的体系结构,不幸的是,我无法再访问任何一台机器进行测试。谢谢你的回答!听起来似乎有道理。
40300000 00000000 16
00000000 00003040 6.1027e-320