[fpc-pascal] Converting big-endian signed 16bits values to fpc integer
Mark Morgan Lloyd
markMLl.fpc-pascal at telemetry.co.uk
Mon Apr 16 09:01:05 CEST 2012
Jonas Maebe wrote:
> On 16 Apr 2012, at 00:38, Giuliano Colla wrote:
>> I'm dealing with a large number of data coming from an external device.
>> They are big-endian 16 bits signed numbers, which must be converted to integer and to real to perform calculations.
>> Besides the obvious solutions of treating them as isolated bytes, multipying by 256 the highest, adding the lower, and oring wit $FFFF0000, or whatever sizeof(Integer) suggests if the result is bigger than 32767, is there a more efficient and elegant way to achieve the result?
> Call BEtoN() on them (Big Endian to Native byte order). Note that this routine is overloaded for all integer sizes > 1, and that FPC extends the size of any number < 32/64 bits (depending on the architecture) to 32/64 bits when performing almost any operation on it. It's therefore probably the safest to call it as BEtoN(smallint(value)) to ensure that the correct overload is selected.
I asked this a few weeks ago in the context of doing endianness-changes
in-place in a data structure, and Martin (I think) suggested overloading
the := operator.
I did however find that one has to be extremely careful inside the
custom operator, I ended up using Move() rather than an assignment to
the result since it was tending to go recursive- some way of inhibiting
all automatic type conversions would be useful.
(* This type represents a little-endian word, irrespective of the
platform. It *)
(* is of known size (16 bits, tested by assertion) but is not directly
(* compatible with any other type.
type WordLE= packed record b0, b1: byte; end;
(* Assign a little-endian word to an (unsigned) integer, with
operator := (wle: WordLE): word;
Type TAWSHeader=packed Record
Mark Morgan Lloyd
markMLl .AT. telemetry.co .DOT. uk
[Opinions above are the author's, not those of his employers or colleagues]
More information about the fpc-pascal