delphi – 如何转换Big Endian以及如何翻转最高位?
我正在使用TStream来读取二进制数据(感谢这篇文章:
How to use a TFileStream to read 2D matrices into dynamic array?).
我的下一个问题是数据是Big Endian.从我的阅读来看,Swap()方法似乎已被弃用.我如何交换下面的类型? 16-bit two's complement binary integer 32-bit two's complement binary integer 64-bit two's complement binary integer IEEE single precision floating-point - Are IEEE affected by Big Endian? 最后,由于数据是无符号的,因此该数据集的创建者已将无符号值存储为有符号整数(不包括IEEE).他们指示只需要添加一个偏移量(2 ^ 15,2 ^ 31和2 ^ 63)来恢复无符号数据.但是,他们注意到,翻转最重要的位是最快的方法.如何有效地翻转16,32或64位整数的最高位? 因此,如果磁盘上的数据(16位)是“85 FB” – 读取数据和交换和位翻转后所需的结果将是1531. 有没有办法完成与泛型的交换和位翻转,所以它适合上面链接的通用答案? 是的,孩子们,这就是NASA,ESO和所有专业天文学家存储科学天文数据的方式.这个FITS标准被一些人认为是其扩散和灵活性中有史以来最成功的标准之一! 解决方法
未经测试:
function Flip16(const Value: Word): Word; inline; begin Result:= Value xor $8000; end; function Flip32(const Value: LongWord): LongWord; inline; begin Result:= Value xor $80000000; end; function Flip64(const Value: UInt64): UInt64; inline; begin Result:= Value xor $8000000000000000; end; function SwapBytes(Value: LongWord): Single; type Bytes = packed array[0..3] of Byte; begin Bytes(Result)[0]:= Bytes(Value)[3]; Bytes(Result)[1]:= Bytes(Value)[2]; Bytes(Result)[2]:= Bytes(Value)[1]; Bytes(Result)[3]:= Bytes(Value)[0]; end; 更新:好吧,如果你要优化:) function SwapBytes(Value: LongWord): Single; register; asm BSWAP EAX end; 再次更新: SO中的常见做法是每个帖子一个问题 – 它通常会产生更好的答案. 1)IEEE是否受Big Endian的影响? 是的,浮点值可以是Big Endians,但这并不意味着您的浮点值是Big Endians – 请检查您的文档. 2)翻转一个最重要的位 – 已经给出了答案,但由于你可能有Big Endians,你可能只需要在最低有效字节中翻转一个最重要的位,即只需x或80美元; 3)将大端转换为小端; 对于16位值使用Swap函数 – 很难理解为什么delphi帮助说该函数仅用于向后兼容; Remko注意到也可以使用XCHG asm指令; 对于32位值,您可以在Marco的评论中使用我的代码或代码; 对于64位值,您可以使用像这样的Marco代码的修改: function Swap64(Value: UInt64): UInt64; begin Result:= Swap32(LongWord(Value)); Result:= (Result shl 32) or Swap32(LongWord(Value shr 32)); end; 4)这里可以使用泛型吗? 我不认为这是个好主意. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |