python2.7 difficulty to convert a binary signed double to ASCII

576 views Asked by At

It will probably sounds like a stupid question but I can not find a way out. I need to read paradox files (.DB) and to convert it in traditional .CSV files. I found a nice module (https://gist.github.com/BertrandBordage/9892556) which does that ... However, some conversions of signed double are not done correctly. That's strange because if I open a DB file with paradox and compared it with what it is converted in the corresponding .csv I can see that : 2, -2 or 2.00 will be correct read from the binary file but -2.00 will not be. All are read from the binary file as a 8-bits double.

I almost sure that all the columns are read correctly by the module cited above but for example when I expect -54.00 (true paradox value) for [63, 180, 255, 255, 255, 255, 255, 255], the module converted to -0.08203125.

So my stupid question is : Is possible that [63, 180, 255, 255, 255, 255, 255, 255] can be convert to -54.00?

Thanks

2

There are 2 answers

1
A. I. Breveleri On

In a Borland BDE (.DB) table, in a Number (N) type column, the value [63, 180, 255, 255, 255, 255, 255, 255] (0x 3FB4 FFFF FFFF FFFF) is indeed equal to -54.00. Any other interpretation is incorrect.

The BDE encodes its Number (N) type as a 64-bit floating-point value, with a sign bit, an 11-bit exponent, and a 53-bit fraction. (I know, that adds up to 65 bits. Keep reading.) The exponent is coded as an excess-1024 integer, so that an exponent of 0 is coded as 0x400. The fraction is normalized to have no leading zeros, adjusting the exponent as necessary. The high-order bit of the fraction is not stored since it is always one. This reduces the fraction storage requirement to 52 bits.

For a positive value, the sign bit is set to one. For a negative value, the absolute value is formed, the sign bit is set to one, and the entire 64 bits complemented.

Zero is encoded as [128, 0, 0, 0, 0, 0, 0, 0] (0x 8000 0000 0000 0000).

This encoding maps the entire range of floating-point values monotonically onto the unsigned 64-bit integers, allowing very speedy comparison and sorting of Number type values without the need to interpret or decode them. (The BDE generally uses a zero sign bit for negative values and a one for positive values so it can form composite indices by simply concatenating the field values and thereafter ignoring the field boundaries.)

0
Michael Herrmann On

I also had to read Paradox (.db) files from Python but BertrandBordage's solution which you link to (also) didn't work for me. I ended up developing Python bindings to the much more complete pxlib library: https://github.com/mherrmann/pypxlib

Install via

pip install pypxlib

Then you can for instance do:

from pypxlib import Table
table = Table('my-paradox.db')
try:
    for row in table:
        print(row)
finally:
    table.close()