Link to home
Start Free TrialLog in
Avatar of scogger1974
scogger1974

asked on

Packed Decimal

I am trying to use Python to convert Packed decimal.  I have already done so in VB6 and Java.  I need to know what command I would use in Python and what syntax I would need to convert it.  Generally in VB6 and in Java I would just convert the Hex code to a string and since I have in my data dictionary the precision of each numeric field i could place the decimal accordingly ... if you can help please do so.. thanks.

scog
Avatar of mish33
mish33
Flag of United States of America image

pd=0x1234567890
dec=int('%x' % pd)
Avatar of scogger1974
scogger1974

ASKER

I am converting this from a file.  I tried the above before and again after your suggestion.
the first conversion to take place in my file is two blank spaces that when I do a repr() on it
i get the below for output.  that is where its dying out on me.  i've tried many different ways
to convert it but still no luck.  I've gotten it converted a few times but it never comes out
with the data that I get in my other programs.

'\x00\x03'

thanks
What exactly is your input format?  Packed decimal is not hex code, though you might conceivably use hex code in the conversion process.  If you could describe a sample input and the desired output, that might help.
Avatar of pepr
# Simulating your file.
f = file('data.bin', 'wb')
f.write('\x00\x03')
f.close()

# Now reading the content of the file.
f = file('data.bin', 'r')
s = f.read()
f.close()

# The s stores the file content. Each byte stores 2 decimals.
result = 0                        # init
for c in s:                       # for each byte
    i = ord(c)                    #    convert it to number
    d1 = (i & 0xf0) >> 4          #    value of upper 4 bits
    d2 = i & 0x0f                 #    value of lower 4 bits
    result = result * 10 + d1     #    accumulate higher digit
    result = result * 10 + d2     #    accumulate lower digit

print result
After the conversion, you may want to use the Python standard module called decimal.
Instead of doing
  repr(x)
do
  z=ord('0')
  int(''.join(chr(ord(c)/256+z)+chr(ord(c)%256+z) for c in x))
ASKER CERTIFIED SOLUTION
Avatar of pepr
pepr

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Also, in "Python Regrets" you can find Relict: "int/int returning int". From this point of view, GvR is against "ord(c)/256" used in the one-liner. ;-)

OK. Just kidding. You can choose what you think is better.
pepr,  Your solution works to a point.  it gives me the digits i need but never in an order that works for converting
I really need the result in a string form with the zero's at the beginning so that i have the results in a predictable place.
otherwise the number could be anything and it won't do me any good.

thanks
So taking a variation of what you gave me this seems to be what I need.
Thanks for your help

class converPack:
    def __init__(self,s,precision):
        result=""
        for c in s:                       # for each byte
            i = ord(c)                    #    convert it to number
            d1 = (i & 0xf0) >> 4          #    value of upper 4 bits
            d2 = i & 0x0f                 #    value of lower 4 bits
            result = result + str(d1)+str(d2)

        self=result
 
I am already familiar with how this stores negative numbers this is a C-ISAM database file and
it is well documented.  Also it helps to know what the real value should be which I do.  

Thanks again.

scog
seems like a typo... You possibly wanted:

        self.strvalue = result

instead of
        self=result
Yep.  As I got that I recived your post.... I'm really new to Python. But I really like it.  I've made some neat tools
for my company in the short time i've used it.  Its soooo fast!.. I've done VB6 Programs that took alot longer to do
that same thing.. not only in time to make but also in the speed of the program.  

Also real quick.  how would I convert the decimal back to packed?  

thanks..
Here is the finished result for converting IBM Packed decimal as it shows up in a C-ISAM database

Command:
fieldValue=converPack(Value,Precision,DecimalPlacement).strvalue
                                      |         |                      |
                     Packed String        |                      |
                    Integer (ex:3,5,7 or 9)                    |
                                                        Integer (0,1,2)

class converPack:   #  This converts IBM Packed Decimal as it works with a C-ISAM Database
    def __init__(self,packed,precision,decimalplace):
        unpacked=""
        sign=""
        for c in packed:                  # for each byte
            i = ord(c)                    #    convert it to number
            d1 = (i & 0xf0) >> 4          #    value of upper 4 bits
            d2 = i & 0x0f                 #    value of lower 4 bits
            unpacked = unpacked + str(d1)+str(d2)   #    add the upper and lower to the string
        if unpacked[:1] == "5": sign="-"  # 3 Means Positive and 5 Means Negative
        unpacked=unpacked[0:precision-decimalplace] + "." + unpacked[precision-decimalplace:precision] #place the decimal
        unpacked=sign+unpacked[0:precision+1].lstrip('0')#    strip the beginning Zero's
        self.strvalue = unpacked  # send the unpacked result back

anyway it may not be perfect yet until I try putting the information in the database and comapre it to what I know
is right fully but just checking random conversions everything seems correct.  Thanks for the help

scog
sorry line 10 in the class should read
 if unpacked[precision+1] == "5": sign="-"  # 3 Means Positive and 5 Means Negative