Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

6 byte real/floating point format?

383 views
Skip to first unread message

David William Poole, Jr.

unread,
Aug 18, 1997, 3:00:00 AM8/18/97
to

My coworker and I have been given the task of deciphering a what we
beleive to be a 6 byte floating point value in a proprietary image
format. We have had no success in locating any information on a 6
byte format, except for Turbo Pascal's Real (if memory serves). Web
searches, and a trip to the local library have proved fruitless. If
any one out there can be of assistance in our endeavor I would greatly
appreciate it.

Please email responses to d...@teleplex.net. My news server is erratic
at best.

TIA!

Vladan Bato

unread,
Aug 21, 1997, 3:00:00 AM8/21/97
to

On Mon, 18 Aug 1997 22:29:11 GMT, d...@teleplex.net (David William
Poole, Jr.) wrote:

>My coworker and I have been given the task of deciphering a what we
>beleive to be a 6 byte floating point value in a proprietary image
>format. We have had no success in locating any information on a 6
>byte format, except for Turbo Pascal's Real (if memory serves). Web
>searches, and a trip to the local library have proved fruitless. If
>any one out there can be of assistance in our endeavor I would greatly
>appreciate it.
>

From the TP Programmer's Guide :
(best viewed with a non-proportional font)

The Real Type

A 6-byte (48-bit) Real number is divided into three fields :

width in bits
1 39 8
+-+--------------------------------------+--------+
|s| f | e |
+-+--------------------------------------+--------+
msb lsb msb lsb

The value v of the number is determined by

if 0<e<=255, then v=(-1)^s * 2^(e-129) * (1.f)
if e=0, then v=0

The Real type cannot store denormals, NaNs, and infinites.Denormals
becomes zero when stored in a Real, and NaNs and infinites produce an
overflow wrror if an attempt is made to store them in a Real.

I hope this helps...

--
(Remove the "removethis" part of the e-mail address to reply)

Vladan Bato
ba...@geocities.com
http://www.geocities.com/SiliconValley/8682/

Terje Mathisen

unread,
Aug 21, 1997, 3:00:00 AM8/21/97
to

Vladan Bato wrote:
>
> On Mon, 18 Aug 1997 22:29:11 GMT, d...@teleplex.net (David William
> Poole, Jr.) wrote:
>
> >My coworker and I have been given the task of deciphering a what we
> >beleive to be a 6 byte floating point value in a proprietary image
> >format. We have had no success in locating any information on a 6
> >byte format, except for Turbo Pascal's Real (if memory serves). Web
> >searches, and a trip to the local library have proved fruitless. If
> >any one out there can be of assistance in our endeavor I would greatly
> >appreciate it.
> >
>
> From the TP Programmer's Guide :
> (best viewed with a non-proportional font)
>
> The Real Type
>
> A 6-byte (48-bit) Real number is divided into three fields :
>
> width in bits
> 1 39 8
> +-+--------------------------------------+--------+
> |s| f | e |
> +-+--------------------------------------+--------+
> msb lsb msb lsb
>
> The value v of the number is determined by
>
> if 0<e<=255, then v=(-1)^s * 2^(e-129) * (1.f)
> if e=0, then v=0

Assuming these fields are all stored in that order, i.e. exp + mant +
sign when going from the least significant bit to the msb, you should be
able to use code like this:

double tp2double(void *real6)
{
unsigned char *r6 = (unsigned char *) real6;
double temp;
unsigned long *ptmp = (unsigned long *) &temp;
unsigned long exp, sign, manth, mantl;

exp = r6[0];
if (!exp) return 0.0;

exp -= 129;
sign = r6[5] >> 7;
mantl = r6[1] + (r6[2] << 8) + (r6[3] << 16) + (r6[4] << 24);
manth = r6[5] & 0x7f;

// Assumes a little-endian machine, switch if otherwise!
#define MSD 1
#define LSD 0

ptmp[MSD] = (sign << 31) // sign bit
+ ((exp + 1023) << 21) // adjusted exponent (11 bits)
+ (manth << 13) // top 7 bits of mantissa
+ (mantl >> 19); // next 13 bits --"--

ptmp[LSD] = mantl << 13; // Final 19 bits of mantissa

return temp;
}

If you construct the result as the sum of two single prec (float)
numbers, then it becomes feasible to make the code endian-independent.

Terje

--
- <Terje.M...@hda.hydro.com>
Using self-discipline, see http://www.eiffel.com/discipline
"almost all programming can be viewed as an exercise in caching"

Wayne D. Hoxsie Jr.

unread,
Aug 22, 1997, 3:00:00 AM8/22/97
to

On Mon, 18 Aug 1997 22:29:11 GMT, d...@teleplex.net (David William
Poole, Jr.) wrote:

>My coworker and I have been given the task of deciphering a what we
>beleive to be a 6 byte floating point value in a proprietary image
>format. We have had no success in locating any information on a 6
>byte format, except for Turbo Pascal's Real (if memory serves). Web
>searches, and a trip to the local library have proved fruitless. If
>any one out there can be of assistance in our endeavor I would greatly
>appreciate it.
>

>Please email responses to d...@teleplex.net. My news server is erratic
>at best.

All floating Point formats include a sign bit, several exponent bits,
and several mantissa bits. These seldom ever line up on byte
boundaries and therefore require bit shifting, etc. to convert between
formats.

There is a normalization process for the mantissa that involves adding
an implied first bit, then dividing by a known value. The actual
exponent is derived by subtracting a known value from the stored
value. Once normalized, the formula for obtaining a "human readable"
representation of a floating point type is:

(2^exp)*(mant)

for example, the hex dump of the IEEE value for 12.51 is:

41 48 28 F6 or 01000001 01001000 00101000 11110110 binary.

This gives:

0 sign bit (positive)
10000010 exponent (82h)
(1)10010000010100011110110 mantissa (C828F6h)

where the extra 1 tacked onto the mantissa is implied.

The exponent is subtracted by 127 to yield 3 --> 2^3=8
The mantissa is divided by 8388608 (100000h) to yield 1.56375002861

The final value is then 8* 1.56375002861 or 12.51000022888.


I was once given the task of converting BASIC floats stored in an old
data file to IEEE floats (as used by C/C++). I decided to study other
floating point formats and came up with the following structure for a
Turbo Pascal 6 byte "REAL" data type (in network byte order--big
endian):

1 sign bit, 39(+1 implied) mantissa, 8 exponent bits

As you can see, the exponent and mantissa are swapped from IEEE
floats. Also, the exponent is subtracted by 129 v 127 and,
the mantissa is normalized with 1000000000h

There are 2 options when converting to a IEEE; either truncate the
value to fit in a 4 byte float, or pad with zeros and stick it into a
8 byte double. I've never bothered with the latter, but I did write a
routine in C to handle the former. I threw in a wrapper that will
read a file called "test.dat" containing the 6 byte "REAL" values and
convert to IEEE float and print the results. Note that there is no
error checking. Use at your own risk:

#include <stdio.h>
#include <stdlib.h>

/*
float 1 sign bit, 8 exponent bits, 23(+1) mantissa bits
TP real 1 sign, 39(+1) mantissa, 8 exponent bits
double 1 sign, 11 exponent bits, 52(+1) mantissa bits
*/

char bar[6];

float p2f(char *foo)
{
float *g;
long sign,exp;
long mant,tmp;

exp=(foo[0]-2)&0xffL;
mant=*(long *)&foo[2];
mant<<=1;
tmp=foo[5]&0x80;
tmp<<=33;
tmp|=exp<<23;
tmp|=mant>>9;
g=(float *)&tmp;
return *g;
}

main()
{
FILE *f;
float q;

f=fopen("test.dat","rb");
fread(&bar,1,6,f);
while(!feof(f)){
q=p2f(bar);
printf("%f\n",q);
fread(&bar,1,6,f);
}
fclose(f);
return 0;
}

If this doesn't work for you, then it may be a proprietary format of
some sort but probably still follows some general rules as above. If
you want to send me a file of a few of these values, I can probably
figure it out for you and modify the above routine to handle them.

Hope this helps.

--
Wayne D. Hoxsie Jr.
wa...@hoxnet.com
http://www.hoxnet.com

0 new messages