On Sun, Feb 05, 2006 at 01:39:25PM +0100, Jonas Maebe wrote:

>

> On 05 Feb 2006, at 13:32, Tom Verhoeff wrote:

>

> >Question 2: Any suggestions as to how to make it more platform

> >independent,

> >or how to support multiple platforms in an easy way?

>

> The only differences are little/big endian. So if it works on PPC and

> I386, you have support for all platforms. Just use {$ifdef

> FPC_LITTLE_ENDIAN}

[This is about IEEE floating-point numbers]

Two further questions.

Which platforms use which endian? (Of course, I could just experiment,

or maybe even read the FPC source, but asking is simpler. :-)

When I looked at my code again, it seems to me that the change that I made

to support both PPC and I386 is not endian-related, but I may be wrong,

or it may be more complicated.

So, here are some pieces of the code, it uses a variant array to

access the bits of the IEEE floating-point numbers in Single and Double:

-----

interface

const

SignIndexSingle = 31; { position of sign bit in single format }

ExpSizeSingle = 8; { size of exponent field in single format }

MaxExpSingle = 255;

ExpBiasSingle = 127;

EminSingle = 1 - ExpBiasSingle;

EmaxSingle = MaxExpSingle - 1 - ExpBiasSingle;

FracSizeSingle = 23; { size of fraction field in single format }

type

BitIndexSingle = 0 .. SignIndexSingle;

ConvertSingle = record

case Boolean of

False: ( d: Single )

; True : ( s: set of BitIndexSingle ) { i in s == bit i = 1 }

end;

procedure WriteBitsSingle ( const x: Single );

procedure WriteBinarySingle ( const x: Single );

function PowerOf2Single ( const x: Single; n: Integer ): Single;

const

SignIndexDouble = 63; { position of sign bit in double format }

ExpSizeDouble = 11; { size of exponent field in double format }

MaxExpDouble = 2047;

ExpBiasDouble = 1023;

EminDouble = 1 - ExpBiasDouble;

EmaxDouble = MaxExpSingle - 1 - ExpBiasDouble;

FracSizeDouble = 52; { size of fraction field in double format }

type

BitIndexDouble = 0 .. SignIndexDouble;

ConvertDouble = record

case Boolean of

False: ( d: Double )

; True : ( s: set of BitIndexDouble ) { i in s == bit i = 1 }

end;

procedure WriteBitsDouble ( const x: Double );

procedure WriteBinaryDouble ( const x: Double );

procedure FlipBitDouble ( var x: Double; i: BitIndexDouble );

function PowerOf2Double ( const x: Double; n: Integer ): Double;

-----

It turns out that my code for the Single type works on both PPC

and I386 without change. However for Double, I had to write e.g.

-----

procedure WriteBitsDouble ( const x: Double );

var c: ConvertDouble; i, i_: BitIndexDouble;

begin

with c do begin

d := x

; for i := SignIndexDouble downto 0 do begin

{$IFDEF CPUPOWERPC}

i_ := (i + 32) mod 64

{$ENDIF}

{$IFDEF CPUI386}

i_ := i

{$ENDIF}

; if i_ in s then write ( '1' )

else write ( '0' )

; if i in [ SignIndexDouble, SignIndexDouble - ExpSizeDouble ] then

write ( ' ' )

end { for i }

end { with c }

end; { WriteBitsDouble }

-----

That is, the lower and upper 32 bits (4 bytes) got swapped.

Maybe this is the case because both the 64-bit set and the Double

get allocated differently depending on endianess?

Can someone enlighten me?

Thanks,

Tom

--

E-MAIL: T.Verhoeff @ TUE.NL | Fac. of Math. & Computing Science

PHONE: +31 40 247 41 25 | Eindhoven University of Technology

FAX: +31 40 247 54 04 | PO Box 513, NL-5600 MB Eindhoven

http://www.win.tue.nl/~wstomv/ | The Netherlands

_______________________________________________

fpc-pascal maillist -

[hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal