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 - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal