困惑了好几天的问题:从二进制文件读一个短整形数,负数不正常

困惑了好几天的问题:从二进制文件读一个短整形数,负数不正常

perl新手,正在用Tk做一个界面。

读一个二进制文件的时候,遇到一个问题,查了好多资料,也没解决。具体是这样:

先把240字节的数据读到一个buffer里:

if(!read(BIN_FILE,$t_header,240)){

        print "error!";

}

这段240字节dump出来就是这样:
  1:00000000   00000001   0000001B   00000000   
005:00000000   00000012   00000001   00010000   
009:00010000   00000000   00000000   00000000   
013:00000000   00000000   00000000   00000000   
017:00000000   D8F0FF9C   01CEB432   19065BC0   
021:00000000   00000000   00030000   00000000   
025:00000000   00000000   00000000   FF9C0012   
029:0012041B   07D00000   00000000   00000000   
033:00000000   00000000   00000000   00000000   
037:00000000   00000000   00000000   00000000   
041:00000000   00000000   00000000   00000000   
045:00000000   00000000   00000000   00000000   
049:00000000   00000000   00000000   00000000   
053:00000000   00000000   00000000   00000000   
057:00000000   00000000   00000000   00000000

我要读的就是红色的部分FF9C,这样读的:

($tmp,$s_t,$tmp)=unpack("H216 H4 H*",$t_header);

把FF9C读到$s_t里,
FF9C的值本来是-100,可打印出来却不是:

printf "start time=%d\n",hex($s_t);

结果是:
start time=65436

查了几天的资料,还是没搞明白。如果读的短整形数是正值,
则打印出来的就是正确的。



哪位明白高手,指点一下
printf "start time=%hd\n",hex($s_t);
为啥要当成有符号数?
unpack 32 位有符号数不能用 H4,得用 i。
那个位置存储的就是一个有符号的数
不是32的的,是一个16位的有符合的整形。


QUOTE:
原帖由 fanfan 于 2008-10-22 15:42 发表
不是32的的,是一个16位的有符合的整形。

16 位的用 s。
用s就有big-endian 或者small-endian的问题了


QUOTE:
原帖由 fanfan 于 2008-10-22 16:05 发表
用s就有big-endian 或者small-endian的问题了

只要和 Real World 之间有 IO,就会有这个问题。你好好整理整理思路吧。我实在不想再说什么了。

BTW:网络格式用 n。

先谢谢了。

本来想偷个懒的

从c转到perl,在数据类型上还真不习惯