Please email responses to d...@teleplex.net. My news server is erratic
at best.
TIA!
>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/
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"
>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