Board index » delphi » Floating point numbers

Floating point numbers

OK guys, I've looked through the group and found a lot of good
information. Now, here's my problem. I'm trying to read 4 bytes of
information that is stored on a Unix 68k machine. These for bytes
represent a floating point number in the format simular to "97.4".
When I try to read this with BP7 I don't come up with anywhere close
to the same number I get on the unix machine. I know it has something
to do with "big endian" , "little endian" but I don't know what to do
in BP7 to read or manipulate it to get the correct number. Can any one
help with this?

Thanks,
Chuck Mayhall
cmayh...@ftlle.fruit.com

 

Re:Floating point numbers


Quote
Chuck Mayhall wrote:

> OK guys, I've looked through the group and found a lot of good
> information. Now, here's my problem. I'm trying to read 4 bytes of
> information that is stored on a Unix 68k machine. These for bytes
> represent a floating point number in the format simular to "97.4".
> When I try to read this with BP7 I don't come up with anywhere close
> to the same number I get on the unix machine. I know it has something
> to do with "big endian" , "little endian" but I don't know what to do
> in BP7 to read or manipulate it to get the correct number. Can any one
> help with this?

You MUST know the format of the number representation of your real
type. Motorola stored numbers in the "wrong" order (as the Intel
people say :-) i.e. the most significant byte on the lowest byte
address.

If you dont know the format, are there at least a few known numbers and
their 4-byte representations available?

You find a related article regarding real number representation in the
1QA - articles of the TP-links. This does not deal with YOUR real type,
but with the Borland-Turbo-Pascal proprietary 6-byte reals. Yet it may
contain some hints for you.
http://www.geocities.com/SiliconValley/2926/tp.html
page "FAQ", look for the red label "1QA" and look in the indes.
--
Franz Glaser, Glasau 3, A-4191 Vorderweissenbach Austria ++43-7219-7035
Muehlviertler Elektronik Glaser. Industrial control and instrumentation
-----------------------------------------------------------------------
http://members.eunet.at/meg-glaser           mailto:meg-gla...@eunet.at
http://www.geocities.com/~franzglaser  http://members.xoom.com/f_glaser

Re:Floating point numbers


On Mon, 01 Mar 1999 00:47:02 GMT,
Quote
bius_cmayh...@pop.birmingham-us.crosswinds.net (Chuck Mayhall) wrote:

                                ^
Good FWP, btw.  Go to http://www.crosswinds.net for unlimited space
and no forced ads whatsover...
==========================================================

Quote
>OK guys, I've looked through the group and found a lot of good
>information. Now, here's my problem. I'm trying to read 4 bytes of
>information that is stored on a Unix 68k machine. These for bytes
>represent a floating point number in the format simular to "97.4".
>When I try to read this with BP7 I don't come up with anywhere close
>to the same number I get on the unix machine. I know it has something
>to do with "big endian" , "little endian" but I don't know what to do
>in BP7 to read or manipulate it to get the correct number. Can any one
>help with this?

OK.  Here, you say you have to read 4 bytes of information.  If it
does have something to do with Big endian / little endian, you will
have to shift the information.  A byte is made up of 8 bits, with
values of 0 or 1.

To accomplish this, you'd have to isolate the bit values and move them
around.

Boolean operators AND, SHL, and SHR will help.  Here's an idea.  Not
tested *too* much, but worked for the two values I put in.  Probably a

much easier way to do it too but haven't thought of it yet.
Hopefully, this will help (and start a good convo).

program shift;

  var
    dataarray: array[1..4] of byte;

  function reverse_byte(inbyte: byte): byte;

    begin
      reverse_byte :=   ((inbyte and $01) shl 7) +
                        ((inbyte and $02) shl 5) +
                        ((inbyte and $04) shl 3) +
                        ((inbyte and $08) shl 1) +
                        ((inbyte and $10) shr 1) +
                        ((inbyte and $20) shr 3) +
                                ((inbyte and $40) shr 5) +
                        ((inbyte and $80) shr 7);

    end;

  begin
    write(reverse_byte($80));  { This one returned 1, as it should
have }
  end.

That reverses the bits in a byte.  Then you could swap the bytes in
dataarray I reckon to get most significant bit as last. (1 for 4 and 2
for 3).

Hope it helps.  If not, hope it gets you on the right track.

Re:Floating point numbers


"Ing. Franz Glaser" <meg-gla...@eunet.at> wrote:

Quote
>Chuck Mayhall wrote:

>> OK guys, I've looked through the group and found a lot of good
>> information. Now, here's my problem. I'm trying to read 4 bytes of
>> information that is stored on a Unix 68k machine. These for bytes
>> represent a floating point number in the format simular to "97.4".
>> When I try to read this with BP7 I don't come up with anywhere close
>> to the same number I get on the unix machine. I know it has something
>> to do with "big endian" , "little endian" but I don't know what to do
>> in BP7 to read or manipulate it to get the correct number. Can any one
>> help with this?

>You MUST know the format of the number representation of your real
>type. Motorola stored numbers in the "wrong" order (as the Intel
>people say :-) i.e. the most significant byte on the lowest byte
>address.

>If you dont know the format, are there at least a few known numbers and
>their 4-byte representations available?

The numbers are the effeciency of a spinning frame which takes raw
cotton and turns it into yarn (thread). These can range from 0.0 to
100.0. The usual range however is from 85.0 to 98.0. The file that is
stored is 400 bytes long which represent 100 machines  (100 4 byte
records). Looking at this file, each 4 byte recored usually begins
with 42 hex. I have manualy manipulated the number (which I may not
have a full grip on what's actually going on) and still con't get it
to come out to the same number the unix machine gives.

- Show quoted text -

Quote
>You find a related article regarding real number representation in the
>1QA - articles of the TP-links. This does not deal with YOUR real type,
>but with the Borland-Turbo-Pascal proprietary 6-byte reals. Yet it may
>contain some hints for you.
>http://www.geocities.com/SiliconValley/2926/tp.html
>page "FAQ", look for the red label "1QA" and look in the indes.
>--
>Franz Glaser, Glasau 3, A-4191 Vorderweissenbach Austria ++43-7219-7035
>Muehlviertler Elektronik Glaser. Industrial control and instrumentation
>-----------------------------------------------------------------------
>http://members.eunet.at/meg-glaser           mailto:meg-gla...@eunet.at
>http://www.geocities.com/~franzglaser  http://members.xoom.com/f_glaser

Re:Floating point numbers


Quote
thed...@lebowski.com (Glenn Grotzinger) wrote:
>On Mon, 01 Mar 1999 00:47:02 GMT,
>bius_cmayh...@pop.birmingham-us.crosswinds.net (Chuck Mayhall) wrote:

I'm not a newbie but not a frequent poster either. What does FWP stand
for?

Quote
>Good FWP, btw.  Go to http://www.crosswinds.net for unlimited space
>and no forced ads whatsover...
>==========================================================
>>OK guys, I've looked through the group and found a lot of good
>>information. Now, here's my problem. I'm trying to read 4 bytes of
>>information that is stored on a Unix 68k machine. These for bytes
>>represent a floating point number in the format simular to "97.4".
>>When I try to read this with BP7 I don't come up with anywhere close
>>to the same number I get on the unix machine. I know it has something
>>to do with "big endian" , "little endian" but I don't know what to do
>>in BP7 to read or manipulate it to get the correct number. Can any one
>>help with this?

>OK.  Here, you say you have to read 4 bytes of information.  If it
>does have something to do with Big endian / little endian, you will
>have to shift the information.  A byte is made up of 8 bits, with
>values of 0 or 1.

>To accomplish this, you'd have to isolate the bit values and move them
>around.

>Boolean operators AND, SHL, and SHR will help.  Here's an idea.  Not
>tested *too* much, but worked for the two values I put in.  Probably a

>much easier way to do it too but haven't thought of it yet.
>Hopefully, this will help (and start a good convo).

>program shift;

>  var
>    dataarray: array[1..4] of byte;

>  function reverse_byte(inbyte: byte): byte;

>    begin
>      reverse_byte :=       ((inbyte and $01) shl 7) +
>                    ((inbyte and $02) shl 5) +
>                    ((inbyte and $04) shl 3) +
>                    ((inbyte and $08) shl 1) +
>                    ((inbyte and $10) shr 1) +
>                    ((inbyte and $20) shr 3) +
>                            ((inbyte and $40) shr 5) +
>                    ((inbyte and $80) shr 7);

>    end;

>  begin
>    write(reverse_byte($80));  { This one returned 1, as it should
>have }
>  end.

>That reverses the bits in a byte.  Then you could swap the bytes in
>dataarray I reckon to get most significant bit as last. (1 for 4 and 2
>for 3).

>Hope it helps.  If not, hope it gets you on the right track.

I've done something simular to this before, but with just 2 bytes. I
later found that I could take the first byte and multiply it by 256
and then add the second byte to it instead of shifting the bytes
around. I wonder if I could come up with somthing like taht for 4
bytes?

Re:Floating point numbers


STOP! This is WRONG!

Little-endian and big-endian means that the BYTES are
reversed, not the BITS !!!!!!

Assuming the data are really in binary format, not ASCII,
this little example will read in your file, and store
the values into an array in the "proper" Intel format,
and then prints out the values.
--
(To answer me, remove the ".net" from my e-mail address)

Arthur M. Hoornweg

Program test;
{$i-,N+}

VAR f,k:integer;
       i:FILE;
       A : ARRAY [1..4] of CHAR;
       B:  Array[1..4] of CHAR;
       R:  Single absolute B;
       mydata:array[1..1000] of single;
begin
    Assign(i,'MYFILE.DAT');
    reset(i,1);
    if ioresult<>0 then halt;
    k:=0;
    repeat
      inc(k);
      blockread(i,A,sizeof(A));
      for f:=1 to 4 do B[f]:=A[5-f];
      mydata[k]:=R;
    until eof(i);
    close(i);
    for f:=1 to k do writeln(mydata[k]:0:4);
end;

--
(To answer me, remove the ".net" from my e-mail address)

Arthur M. Hoornweg

Re:Floating point numbers


Quote
>I've done something simular to this before, but with just 2 bytes. I
>later found that I could take the first byte and multiply it by 256
>and then add the second byte to it instead of shifting the bytes
>around. I wonder if I could come up with somthing like taht for 4
>bytes?

Haha, the compiler fooled you! (c:

Actually, when you multiply by 256, the compiler will recognise this as the
same as shifting 8 bits to the left, and do that instead, as it is a lot
faster.

/GreenGhost
________________________
Kill the spammer to mail me
________________________
http://hem.passagen.se/guffa/

Re:Floating point numbers


JRS:  In article <36d9fcb9.27704...@news.iland.net> of Mon, 1 Mar 1999
03:10:37 in news:comp.lang.pascal.borland, Glenn Grotzinger

Quote
<thed...@lebowski.com> wrote:
>On Mon, 01 Mar 1999 00:47:02 GMT,
>bius_cmayh...@pop.birmingham-us.crosswinds.net (Chuck Mayhall) wrote:
>                               ^
>Good FWP, btw.  Go to http://www.crosswinds.net for unlimited space
>and no forced ads whatsover...
>==========================================================
>>OK guys, I've looked through the group and found a lot of good
>>information. Now, here's my problem. I'm trying to read 4 bytes of
>>information that is stored on a Unix 68k machine. These for bytes
>>represent a floating point number in the format simular to "97.4".
>>When I try to read this with BP7 I don't come up with anywhere close
>>to the same number I get on the unix machine. I know it has something
>>to do with "big endian" , "little endian" but I don't know what to do
>>in BP7 to read or manipulate it to get the correct number. Can any one
>>help with this?

>OK.  Here, you say you have to read 4 bytes of information.  If it
>does have something to do with Big endian / little endian, you will
>have to shift the information.  A byte is made up of 8 bits, with
>values of 0 or 1.

>To accomplish this, you'd have to isolate the bit values and move them
>around.
> ...

I would be rather surprised if the bits of a byte were in the wrong
order, though it is quite likely that the four bytes are in the wrong
order.

Chuck should post a table of half a dozen examples of the input in Hex
and the value encoded in them - for example (made up!)
  52667E54 -> 94.6
  5322D347 -> 95.8
...

and, to be helpful, convert to binary
  52667E54 = 01010010 01100110 01111110 01010100 -> 94.6
...

and to be very helpful convert the numbers too
  94.6 = 2^7 * 0.7390625 = 2^7 * 0.10111101..
where the fractional binary part is got by repeatedly doubling the
fractional part and recording the integer part (double & record oddness
will do).

The answer should then be obvious, assuming reasonable encoding on the
68k.

--
John Stockton, Surrey, UK.    j...@merlyn.demon.co.uk    Turnpike v4.00    MIME.
  Web <URL: http://www.merlyn.demon.co.uk/> - TP/BP/&c. FAQqish topics & links.
  Timo's TurboPascal <A HREF="ftp://garbo.uwasa.fi/pc/link/tsfaqp.zip">FAQ</A>.
  <A HREF="http://www.merlyn.demon.co.uk/clpb-faq.txt">Mini-FAQ</A> of c.l.p.b.

Re:Floating point numbers


Dr John Stockton <j...@merlyn.demon.co.uk> wrote:

Quote
>JRS:  In article <36d9fcb9.27704...@news.iland.net> of Mon, 1 Mar 1999
>03:10:37 in news:comp.lang.pascal.borland, Glenn Grotzinger
><thed...@lebowski.com> wrote:
>>On Mon, 01 Mar 1999 00:47:02 GMT,
>>bius_cmayh...@pop.birmingham-us.crosswinds.net (Chuck Mayhall) wrote:
>>                               ^
>>Good FWP, btw.  Go to http://www.crosswinds.net for unlimited space
>>and no forced ads whatsover...
>>==========================================================
>>>OK guys, I've looked through the group and found a lot of good
>>>information. Now, here's my problem. I'm trying to read 4 bytes of
>>>information that is stored on a Unix 68k machine. These for bytes
>>>represent a floating point number in the format simular to "97.4".
>>>When I try to read this with BP7 I don't come up with anywhere close
>>>to the same number I get on the unix machine. I know it has something
>>>to do with "big endian" , "little endian" but I don't know what to do
>>>in BP7 to read or manipulate it to get the correct number. Can any one
>>>help with this?

>>OK.  Here, you say you have to read 4 bytes of information.  If it
>>does have something to do with Big endian / little endian, you will
>>have to shift the information.  A byte is made up of 8 bits, with
>>values of 0 or 1.

>>To accomplish this, you'd have to isolate the bit values and move them
>>around.
>> ...

>I would be rather surprised if the bits of a byte were in the wrong
>order, though it is quite likely that the four bytes are in the wrong
>order.

>Chuck should post a table of half a dozen examples of the input in Hex
>and the value encoded in them - for example (made up!)
>  52667E54 -> 94.6
>  5322D347 -> 95.8
>...

>and, to be helpful, convert to binary
>  52667E54 = 01010010 01100110 01111110 01010100 -> 94.6
>...

>and to be very helpful convert the numbers too
>  94.6 = 2^7 * 0.7390625 = 2^7 * 0.10111101..
>where the fractional binary part is got by repeatedly doubling the
>fractional part and recording the integer part (double & record oddness
>will do).

>The answer should then be obvious, assuming reasonable encoding on the
>68k.

>--
>John Stockton, Surrey, UK.    j...@merlyn.demon.co.uk    Turnpike v4.00    MIME.
>  Web <URL: http://www.merlyn.demon.co.uk/> - TP/BP/&c. FAQqish topics & links.
>  Timo's TurboPascal <A HREF="ftp://garbo.uwasa.fi/pc/link/tsfaqp.zip">FAQ</A>.
>  <A HREF="http://www.merlyn.demon.co.uk/clpb-faq.txt">Mini-FAQ</A> of c.l.p.b.

It was a big endian/little endian thing. Here are the 4 byte of one of
the numbers: 42 C7 12 F7 which, by what i've come up with from you
guys, is 99.5. I used the following, posted here in a reply, and it
worked.

Program test;
{$i-,N+}

VAR f,k:integer;
        i:FLE;
        A : Array[1..4] of char;
        B : Array[1..4] of char;
        R : Single absolute B;
        mydata:array[1..1000] of single;

begin
        Assign(i,'MYFILE.DAT');
        reset(i,1);
        if ioresult<>0 then halt;
        k:=0;
        repeat
                inc(k);
                blockread(i,A,sizeof (A));
                for f:= 1 to 4 do B[f] := A[5-f];
                mydata[k] := R;
        until eof(i);
        close(i);
        for f := 1 to k do writeln(mydata[f]:0:4);
end;

Thanks for all the responces. If anyone has a shorter method, I would
be interested in seeing it.

Thanks again,
Chuck Mayhall

Re:Floating point numbers


On Mon, 1 Mar 1999 08:22:09 +0100, "Arthur Hoornweg"

Quote
<arthur.hoorn...@email.de.net> wrote:
>STOP! This is WRONG!

>Little-endian and big-endian means that the BYTES are
>reversed, not the BITS !!!!!!

It all depends on the format I guess.  Some formats I've worked with
are reversed based on the bits.  But it's all relative, since there's
so many different formats out there.

Re:Floating point numbers


On Mon, 01 Mar 1999 03:57:27 GMT, Chuck Mayhall

Quote
<bius_cmayh...@pop.birmingham-us.crosswinds.net> wrote:
>thed...@lebowski.com (Glenn Grotzinger) wrote:

>>On Mon, 01 Mar 1999 00:47:02 GMT,
>>bius_cmayh...@pop.birmingham-us.crosswinds.net (Chuck Mayhall) wrote:
>>                                            ^
>>Good FWP, btw.  Go to http://www.crosswinds.net for unlimited space
>>and no forced ads whatsover...
>I'm not a newbie but not a frequent poster either. What does FWP stand
>for?

When he wrote that, he included a caret pointing at "crosswinds" as I
replace above, so my guess is that FWP means "free webspace provider" or
something similar. Free Whatever Provider. =)

Quote
>> Glenn's example snipped

As others have suspected and said, converting Big Endian to Little Endian
only involves the bytes, not the bits. Here's a snippet to help:

   {$N+}
   type
      TFourBytes = array [ 0..3 ] of byte;
   var
      beData : TFourBytes; { BigEndian data }
      leData : TFourBytes; { LittleEndian data }

      value  : single absolute leData;
      { value is "overlayed" on leData; they share the same memory }

   begin
      { open file for binary reading }      
      BlockRead( f, beData, 4 );

      leData[ 0 ] := beData[ 3 ]; { converting beData into leData }
      leData[ 1 ] := beData[ 2 ]; { converts it into value at the }
      leData[ 2 ] := beData[ 1 ]; { same time }
      leData[ 3 ] := beData[ 0 ];

      writeln( 'the value is ', value );
   end;

Cheers, Todd

Re:Floating point numbers


JRS:  In article <7bidd8$...@lotho.delphi.com> of Wed, 3 Mar 1999
04:22:00 in news:comp.lang.pascal.borland, Todd Fiske

Quote
<tfi...@delphi.com> wrote:
>As others have suspected and said, converting Big Endian to Little Endian
>only involves the bytes, not the bits. Here's a snippet to help:

>   {$N+}
>   type
>      TFourBytes = array [ 0..3 ] of byte;
>   var
>      beData : TFourBytes; { BigEndian data }
>      leData : TFourBytes; { LittleEndian data }

>      value  : single absolute leData;
>      { value is "overlayed" on leData; they share the same memory }

>   begin
>      { open file for binary reading }      
>      BlockRead( f, beData, 4 );

>      leData[ 0 ] := beData[ 3 ]; { converting beData into leData }
>      leData[ 1 ] := beData[ 2 ]; { converts it into value at the }
>      leData[ 2 ] := beData[ 1 ]; { same time }
>      leData[ 3 ] := beData[ 0 ];

>      writeln( 'the value is ', value );
>   end;

Seems longer than needed :

   {$N+}
   type
      TFourBytes = array [ 0..1 ] of word;                 { <--- }
   var
      beData : TFourBytes; { BigEndian data }
      leData : TFourBytes; { LittleEndian data }

      value  : single absolute leData;
      { value is "overlayed" on leData; they share the same memory }

   begin
      { open file for binary reading }      
      BlockRead( f, beData, 4 );

      leData[0] := swap(beData[1]); { converting beData into leData }
      leData[1] := swap(beData[0]); { converts it into value at the }
                                    { same time }

      writeln( 'the value is ', value );
   end;

Swap tested, above untested.

--
John Stockton, Surrey, UK.    j...@merlyn.demon.co.uk    Turnpike v4.00    MIME.
  Web <URL: http://www.merlyn.demon.co.uk/> - TP/BP/&c. FAQqish topics & links.
  Timo's TurboPascal <A HREF="ftp://garbo.uwasa.fi/pc/link/tsfaqp.zip">FAQ</A>.
  <A HREF="http://www.merlyn.demon.co.uk/clpb-faq.txt">Mini-FAQ</A> of c.l.p.b.

Re:Floating point numbers


On Wed, 3 Mar 1999 12:21:54 +0000, Dr John Stockton

Quote
<j...@merlyn.demon.co.uk> wrote:
>>   {$N+}
>>   type
>>      TFourBytes = array [ 0..3 ] of byte;
>>   var
>>      beData : TFourBytes; { BigEndian data }
>>      leData : TFourBytes; { LittleEndian data }

>>      value  : single absolute leData;
>>      { value is "overlayed" on leData; they share the same memory }

>>   begin
>>      { open file for binary reading }      
>>      BlockRead( f, beData, 4 );

>>      leData[ 0 ] := beData[ 3 ]; { converting beData into leData }
>>      leData[ 1 ] := beData[ 2 ]; { converts it into value at the }
>>      leData[ 2 ] := beData[ 1 ]; { same time }
>>      leData[ 3 ] := beData[ 0 ];

>>      writeln( 'the value is ', value );
>>   end;
>Seems longer than needed :

Depends on what the "need" is, but in any case, I'm sure it is. =)

I don't prefer brevity or cleverness in things that can be difficult to
understand. As far as the computer is concerned (compilation, execution)
the differences are probably negligible, while for the reader, the explicit
structure of TFourBytes and the "unrolled loop" conversion pretty clearly
show what's going on.

Plus, I'm always happy to provide opportunities for further optimising. =)

- Show quoted text -

Quote
>   {$N+}
>   type
>      TFourBytes = array [ 0..1 ] of word;                 { <--- }
>   var
>      beData : TFourBytes; { BigEndian data }
>      leData : TFourBytes; { LittleEndian data }

>      value  : single absolute leData;
>      { value is "overlayed" on leData; they share the same memory }

>   begin
>      { open file for binary reading }      
>      BlockRead( f, beData, 4 );

>      leData[0] := swap(beData[1]); { converting beData into leData }
>      leData[1] := swap(beData[0]); { converts it into value at the }
>                                    { same time }

>      writeln( 'the value is ', value );
>   end;

>Swap tested, above untested.

But then swap() also requires extra code and extra calls. I don't recall
what your swap() routine looks like. What's faster, two swap calls and two
word assignments, or four byte assignments?

Cheers, Todd

Re:Floating point numbers


JRS:  In article <7c45nh$...@lotho.delphi.com> of Tue, 9 Mar 1999
22:01:21 in news:comp.lang.pascal.borland, Todd Fiske

Quote
<tfi...@delphi.com> wrote:

>But then swap() also requires extra code and extra calls. I don't recall
>what your swap() routine looks like. What's faster, two swap calls and two
>word assignments, or four byte assignments?

Swap is a standard part of TP4 & BP7 (& I believe we can safely
interpolate); it is done by the compiler.

        A := Swap(B) ;
gives in BP7, by TD V C,  
        mov ax,[0052] ; xchg ah,al ; mov [0050],ax

The code for the case in question should be similar, as a fixed element
of an array is treated as a simple variable.  There should be two word
assignments, with an xchg in the middle of each.

--
John Stockton, Surrey, UK.    j...@merlyn.demon.co.uk    Turnpike v4.00    MIME.
  Web <URL: http://www.merlyn.demon.co.uk/> - TP/BP/&c. FAQqish topics & links.
  Timo's TurboPascal <A HREF="ftp://garbo.uwasa.fi/pc/link/tsfaqp.zip">FAQ</A>.
  <A HREF="http://www.merlyn.demon.co.uk/clpb-faq.txt">Mini-FAQ</A> of c.l.p.b.

Other Threads