Subject | RE: [ib-support] Firebird Workbench, number formats, retrieving data with API |
---|---|
Author | Henrik Sitter |
Post date | 2003-01-26T13:51:38Z |
Hi, Ann.
Well, I figured it out :) I've never dealt with double precision before
so I didn't know the coding. It turned out that I misunderstood the
fraction part of the formula.
For IEEE the formula to convert back to a decimal number is:
Decimal number = (-1)^(signbit)*2^(exponentbits-1023)*1.fractionbits.
Pretty straight forward, but as I said I misunderstood the last part of
the equation. If the decimal representation of the fractionbits equaled
19992000... (or something) I thought the formula read:
Decimal number = (-1)^(signbit)*2^(exponentbits-1023)*1.19992000...
But this is the wrong interpretation. For those interested I'll provide
an example on how it's done:
Let's say you have stored 201 as double (8 bytes), and have the
following code (C/C++ code):
double Test = 201;
char* TestAdr = (char*) &Test; // Store the address of byte 1 of Test
If you now look in your memory (your machine's), and assuming your
machine use IEEE floating point coding, you will see this:
*(TestAdr + 0) = 0 (= 00000000 in binary) (bits 7 to 0)
*(TestAdr + 1) = 0 (= 00000000 in binary) (bits 15 to 8)
*(TestAdr + 2) = 0 (= 00000000 in binary) (bits 23 to 16)
*(TestAdr + 3) = 0 (= 00000000 in binary) (bits 31 to 24)
*(TestAdr + 4) = 0 (= 00000000 in binary) (bits 39 to 32)
*(TestAdr + 5) = 32 (= 00100000 in binary) (bits 47 to 40)
*(TestAdr + 6) = 105 (= 01101001 in binary) (bits 55 to 48)
*(TestAdr + 7) = 64 (= 01000000 in binary) (bits 63 to 56)
1) Signbit: bit 63 = 0 (the leftmost bit in the last line above)
2) Exponent: bits 62 to 52 (eleven bits) = 10000000110 = 1030 in decimal
representation.
3) Fraction/mantissa: bits 51 to 0 = 100100100...0000 (the leftmost bit
here is bit 51).
How should one interpret these fraction/mantissa bits. If a bit = 1, it
is assigned a value, if the bit = 0 it's assigned the value 0.
Bit51 = 1 -> assign the value 0.5
Bit50 = 1 -> assign the value 0.5/2 = 0.25
Bit49 = 1 -> assign the value 0.25/2 = 0.125
Bit48 = 1 -> assign the value 0.125/2 = 0.0625
Bit47 = 1 -> assign the value 0.0625/2 = 0.03125
Bit46 = 1 -> assign the value 0.03125/2 = 0.015625
Bit45 = 1 -> assign the value 0.015625/2= 0.0078125
.
.
and so on.
In our fraction/mantissa bit51, bit48 and bit45 is lit. So our fraction
becomes: 0.5 + 0.0625 +0.0078125 = 0.5703125
What we get using the decoding formula
"Decimal number = (-1)^(signbit)*2^(exponentbits-1023)*1.fractionbits"
is:
Decimal number = (-1)^0*2^(1030-1023)*1.5702125 = 201 (fantastic...)
Well, this was a long post about something easy, but just in case
somebody wondered about those fraction bits, I hope this explains it a
bit.
Henrik
-----Original Message-----
From: Ann W. Harrison [mailto:aharrison@...]
Sent: Sunday, January 26, 2003 12:18 AM
To: ib-support@yahoogroups.com; ib-support@yahoogroups.com
Subject: RE: [ib-support] Firebird Workbench, number formats, retrieving
data with API
At 11:54 PM 1/25/2003 +0100, Henrik Sitter wrote:
in the appropriate format for the client. The data is sent
over the wire in XDR (basically the native Sun format of
1985) and translated at either end to the native format of
the server (at one end) or client (at the other).
exponent of a floating point number don't align neatly
on byte boundaries, which may explain this confusion. Being
a slothful person, I haven't looked hard at your code, but
if you're writing in C, have you tried a printf of the
value returned? Or declaring an appropriate variable,
assigning values to it and comparing those, bytewise, with
what you're seeing?
Regards,
Ann
www.ibphoenix.com
We have answers.
To unsubscribe from this group, send an email to:
ib-support-unsubscribe@egroups.com
Your use of Yahoo! Groups is subject to
http://docs.yahoo.com/info/terms/
Well, I figured it out :) I've never dealt with double precision before
so I didn't know the coding. It turned out that I misunderstood the
fraction part of the formula.
For IEEE the formula to convert back to a decimal number is:
Decimal number = (-1)^(signbit)*2^(exponentbits-1023)*1.fractionbits.
Pretty straight forward, but as I said I misunderstood the last part of
the equation. If the decimal representation of the fractionbits equaled
19992000... (or something) I thought the formula read:
Decimal number = (-1)^(signbit)*2^(exponentbits-1023)*1.19992000...
But this is the wrong interpretation. For those interested I'll provide
an example on how it's done:
Let's say you have stored 201 as double (8 bytes), and have the
following code (C/C++ code):
double Test = 201;
char* TestAdr = (char*) &Test; // Store the address of byte 1 of Test
If you now look in your memory (your machine's), and assuming your
machine use IEEE floating point coding, you will see this:
*(TestAdr + 0) = 0 (= 00000000 in binary) (bits 7 to 0)
*(TestAdr + 1) = 0 (= 00000000 in binary) (bits 15 to 8)
*(TestAdr + 2) = 0 (= 00000000 in binary) (bits 23 to 16)
*(TestAdr + 3) = 0 (= 00000000 in binary) (bits 31 to 24)
*(TestAdr + 4) = 0 (= 00000000 in binary) (bits 39 to 32)
*(TestAdr + 5) = 32 (= 00100000 in binary) (bits 47 to 40)
*(TestAdr + 6) = 105 (= 01101001 in binary) (bits 55 to 48)
*(TestAdr + 7) = 64 (= 01000000 in binary) (bits 63 to 56)
1) Signbit: bit 63 = 0 (the leftmost bit in the last line above)
2) Exponent: bits 62 to 52 (eleven bits) = 10000000110 = 1030 in decimal
representation.
3) Fraction/mantissa: bits 51 to 0 = 100100100...0000 (the leftmost bit
here is bit 51).
How should one interpret these fraction/mantissa bits. If a bit = 1, it
is assigned a value, if the bit = 0 it's assigned the value 0.
Bit51 = 1 -> assign the value 0.5
Bit50 = 1 -> assign the value 0.5/2 = 0.25
Bit49 = 1 -> assign the value 0.25/2 = 0.125
Bit48 = 1 -> assign the value 0.125/2 = 0.0625
Bit47 = 1 -> assign the value 0.0625/2 = 0.03125
Bit46 = 1 -> assign the value 0.03125/2 = 0.015625
Bit45 = 1 -> assign the value 0.015625/2= 0.0078125
.
.
and so on.
In our fraction/mantissa bit51, bit48 and bit45 is lit. So our fraction
becomes: 0.5 + 0.0625 +0.0078125 = 0.5703125
What we get using the decoding formula
"Decimal number = (-1)^(signbit)*2^(exponentbits-1023)*1.fractionbits"
is:
Decimal number = (-1)^0*2^(1030-1023)*1.5702125 = 201 (fantastic...)
Well, this was a long post about something easy, but just in case
somebody wondered about those fraction bits, I hope this explains it a
bit.
Henrik
-----Original Message-----
From: Ann W. Harrison [mailto:aharrison@...]
Sent: Sunday, January 26, 2003 12:18 AM
To: ib-support@yahoogroups.com; ib-support@yahoogroups.com
Subject: RE: [ib-support] Firebird Workbench, number formats, retrieving
data with API
At 11:54 PM 1/25/2003 +0100, Henrik Sitter wrote:
>Thanks for your reply. I'm trying to decode the binary representationof
>a float (using firebird v.1.0.0). Do you know if "IEEE 754 floatingAh! That's easy. IEEE. Except on VAXes.
>point", "D_FLOAT floating point" or "G_FLOAT floating point" is used?
>What about big endian or little endian?Depends on your client architecture. Firebird returns values
in the appropriate format for the client. The data is sent
over the wire in XDR (basically the native Sun format of
1985) and translated at either end to the native format of
the server (at one end) or client (at the other).
>So far I have not been able to decode correctly (trying all three (orErrr... If I remember correctly, the sign, mantissa, and
>six) encodings), but I have done some testing and I'm pretty sure that
>my database returns the correct binary representation. Here are some
>examples:
>
>If I store 201 (as float/double precision), it returns:
>Byte 7: 64
>Byte 6: 105
>Byte 5: 32
>Byte 4 to byte 0: 0
>
>If I store 202 (as float/double precision), it returns:
>Byte 7: 64
>Byte 6: 105
>Byte 5: 64 (+32 compared to storing 201)
>Byte 4 to byte 0: 0
>
>If I store 203 (as float/double precision), it returns:
>Byte 7: 64
>Byte 6: 105
>Byte 5: 96 (+32 compared to storing 202)
>Byte 4 to byte 0: 0
exponent of a floating point number don't align neatly
on byte boundaries, which may explain this confusion. Being
a slothful person, I haven't looked hard at your code, but
if you're writing in C, have you tried a printf of the
value returned? Or declaring an appropriate variable,
assigning values to it and comparing those, bytewise, with
what you're seeing?
Regards,
Ann
www.ibphoenix.com
We have answers.
To unsubscribe from this group, send an email to:
ib-support-unsubscribe@egroups.com
Your use of Yahoo! Groups is subject to
http://docs.yahoo.com/info/terms/