Subject RE: [ib-support] Firebird Workbench, number formats, retrieving data with API Henrik Sitter 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:

of
>a float (using firebird v.1.0.0). Do you know if "IEEE 754 floating
>point", "D_FLOAT floating point" or "G_FLOAT floating point" is used?

Ah! That's easy. IEEE. Except on VAXes.

>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 (or
>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

Errr... If I remember correctly, the sign, mantissa, and
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