How to convert Big Endian and how to flip the highest bit?

前端 未结 2 529
慢半拍i
慢半拍i 2021-01-19 16:46

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?).

My next problem is that the data is

相关标签:
2条回答
  • 2021-01-19 17:27

    Well, I don't know too much about byte swapping, but flipping a single bit is easy. XOR your value with a mask whose binary representation is all 0s, except for a 1 for the bit you want to flip. If you want the most significant bit, in hex that works out to $80 for a single byte, $8000 for a word and, you guessed it, $80000000 for a double word.

    0 讨论(0)
  • 2021-01-19 17:39

    Not tested:

    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;
    

    Updated once more:

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

    1) Are IEEE affected by Big Endian?

    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) 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) converting big endian to little endian;

    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;

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

    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) Is it possible to use generics here?

    I don't think it is a good idea.

    0 讨论(0)
提交回复
热议问题