如何转换Big Endian以及如何翻转最高位? [英] How to convert Big Endian and how to flip the highest bit?

查看:157
本文介绍了如何转换Big Endian以及如何翻转最高位?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用TStream读取二进制数据(由于这篇文章:如何使用TFileStream将2D矩阵读入动态数组?)。

I am using a TStream to read binary data (thanks to this post: How to use a TFileStream to read 2D matrices into dynamic array?).

我的下一个问题是数据是Big Endian。根据我的阅读,Swap()方法似乎已被弃用。我将如何交换以下类型?

My next problem is that the data is Big Endian. From my reading, the Swap() method is seemingly deprecated. How would I swap the types below?

 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位整数的最高有效位?

And, finally, since the data is unsigned, the creators of this dataset have stored the unsigned values as signed integers (excluding the IEEE). They instruct that one need only add an offset (2^15, 2^31, and 2^63) to recover the unsigned data. But, they note that flipping the most significant bit is the fastest way to do that. How does one efficiently flip the most significant bit of a 16, 32, or 64-bit integer?

因此,如果磁盘(16位)上的数据是 85 FB-读取数据并进行交换和位翻转后的理想结果将是1531。

So, if the data on disk (16-bit) is "85 FB" - the desired result after reading the data and swapping and bit flipping would be 1531.

有没有一种方法可以用泛型完成交换和位翻转,因此是否适合上面链接中的通用答案?

Is there a way to accomplish the swapping and bit flipping with generics so it fits into the generic answer at the link above?

是的,孩子们,这是NASA,ESO和所有专业天文学家存储科学天文数据的方式。某些人认为此FITS标准是其扩散和灵活性方面最成功的标准之一!

Yes, kids, THIS is how scientific astronomical data is stored by NASA, ESO, and all professional astronomers. This FITS standard is considered by some to be one of the most successful standards ever created in its proliferation and flexibility!

推荐答案

未经测试:

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;






已更新:很好如果您要优化:)


Updated: Well if you about to optimize :)

function SwapBytes(Value: LongWord): Single; register; 
asm
  BSWAP  EAX
end;






再次更新

SO中的一种常见做法是每个帖子发一个问题-通常可以得到更好的答案。

A common practice in SO is one question per one post - it generally results in better answers.

1)IEEE是否受到Big Endian的影响?

1) Are IEEE affected by Big Endian?

是的,浮点值可以是Big Endians,但这并不意味着您的浮点值是Big Endians-

Yes, floating-point values can be Big Endians, but it does not mean that your floating-point values are Big Endians - check your documentation.

2)翻转最高有效位-答案已经给出,但是由于您可能拥有Big Endians,因此您可能只需要翻转最高有效位最低有效字节,即xor $ 80;

2) flipping a most significant bit - the answer is already given, but since you probably have Big Endians you may need just to flip a most significant bit in a least significant byte, i.e. just xor $80;

3)将大字节序转换为小字节序;

3) converting big endian to little endian;

对于16位值,请使用Swap函数-很难理解为什么delphi help表示该函数仅用于向后兼容;如Remko所注意到的,也可以使用XCHG asm指令;

for 16-bit values use Swap function - it is hard to understand why delphi help says that the function is for backward compatibility only; it is also possible to use XCHG asm instruction as Remko noticed;

对于32位值,您可以使用我的代码或Marco注释中的代码;

for 32-bit values your can use my code or code in Marco's comment;

对于32位值值,您可以使用对Marco的代码进行如下修改:

for 64-bit values you can use a modification of Marco's code like this:

function Swap64(Value: UInt64): UInt64;
begin
  Result:= Swap32(LongWord(Value));
  Result:= (Result shl 32) or Swap32(LongWord(Value shr 32));
end;

4)是否可以在此处使用泛型?

4) Is it possible to use generics here?

我认为这不是一个好主意。

I don't think it is a good idea.

这篇关于如何转换Big Endian以及如何翻转最高位?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆