To write the first blog took me some time though there are few topics in my mind which I think I should blog. To write a blog with the right contents and presenting in a way which is very helpful for others is a challenge and hats off to al the bloggers for their efforts. I have been a constant follower of scn blogs and many such blogs has helped me a lot. So this is my first humble attempt to share something which I feel would help anyone who come across similar issue.
The topic is about packed number. Recently I came across an issue with one of our customers where they having issues storing large amount value to a packed decimal field. It was throwing overflow exception . To solve this issue I tried searching to get to know how packed decimals behave I couldn't get enough details anywhere about the exact behavior of packed decimals and i had spend some time to write a test program to understand the right behavior of packed decimals.
Customer was having a custom domain of data type dec length 16 and decimal 9 .Based on the various documentations on packed number our assumption was that we have created a packed number with maximum length possible which is length 16 .
The amount value we were trying to store is 100000000.00. 9 digits before the decimal and 2 digits after the decimal .We were getting an overflow exception .I could see from the amount value if i reduce the number of digits before the decimal by one the overflow exception doesn't happen ( 8 digits before the decimal and 9 digits after the decimal ) . This made me wonder what's the length all about and how it works in case of packed decimal . I spend some time debugging the issue.
Below is how it appeared in the debugger .
What I understand is though I have declared my domain is of length 16 and dec 9 ,internally system converts into a packed decimal of length 9 and
dec 9 .P(9) DECIMAL 9.Now I had to understand what's this length stands for ,what does it mean by length 9 in case of packed decimal.
Predefined Numeric Types is explained here ABAP Keyword Documentation
Based on definitions about packed decimal length 9 means 9 bytes and 2 digits forms 1 byte and so the actual length is 18 digits which includes one space for +/- sign. So in this case a domain declared with the length 16 and decimal 9 is converted by the system as a packed decimal of length 9 and decimal 9 which means a total of 18 digits including 9 decimal and 8 digits before the decimal and one space for the sign . Now I understood the reason why the amount 100000000.00 was not accepted by the variable ,instead 10000000.00 was accepted .
Overview of All Predefined Dictionary Types is explained here ABAP Keyword Documentation
Below is the test program to understand more about packed decimals.
REPORT ZTEST_PROGRAM
*Data Declarations
data lv_char(50) value '9.999999999'.
data: lv_p TYPE p LENGTH 16 DECIMALS 9.
data: lv_num type i value 1.
data: lv_dec type i value 9.
write:/ 'Keeping Decimal place constant as 9'.
DO 25 TIMES.
lv_num = lv_num + 1.
CONCATENATE '9' lv_char into lv_char.
TRY .
lv_p = lv_char.
CATCH CX_SY_CONVERSION_OVERFLOW .
write:/'overflow'.
ENDTRY.
CHECK lv_p is NOT INITIAL.
write:/ lv_p, lv_num ,'Numbers and', lv_dec,' Decimals'.
ENDDO.
uline.
write:/ 'Keeping Decimal place constant as 9 in the situation'.
CLEAR: lv_num,lv_dec,lv_p,lv_char.
lv_char = '9.999999999'.
lv_num = 1. lv_dec = 9.
DO 10 TIMES.
lv_num = lv_num + 1.
CONCATENATE '9' lv_char into lv_char.
TRY .
lv_p2 = lv_char.
CATCH CX_SY_CONVERSION_OVERFLOW .
write:/'overflow'.
ENDTRY.
CHECK lv_p2 is NOT INITIAL.
write:/ lv_p2, lv_num ,'Numbers and', lv_dec,' Decimals'.
ENDDO.
uline.
write:/ 'Keeping Decimal place constant as 3'.
CLEAR: lv_num,lv_dec,lv_p,lv_char.
data: lv_p1 TYPE p LENGTH 9 DECIMALS 3.
lv_char = '9.999'.
lv_num = 1.
lv_dec = 3.
DO 20 TIMES. lv_num = lv_num + 1.
CONCATENATE '9' lv_char into lv_char.
TRY .
lv_p1 = lv_char.
CATCH CX_SY_CONVERSION_OVERFLOW .
write:/'overflow'.
ENDTRY.
CHECK lv_p1 is NOT INITIAL.
write:/ lv_p1, lv_num ,'Numbers and', lv_dec,' Decimals'.
ENDDO.
If we have to keep the length fixed for the domain( declared length 16 decimal 9 ) , reduce the decimal points to hold more digits before the decimal .Below is a screenshot to show when the overflow will occur for the used domain reducing the decimal is reduced to 3 digits. Below is the output from the above code . This shows 14 Numbers are possible before decimal and 3 numbers after decimal.
So what we have to understand is the length defined in the domain is not the actual length of the packed decimal. if I declare a domain of length 20 and decimal 9 ,in debugger I could see the system converts it to a packed decimal of length 11 and decimal 9.The maximum allowed length of packed decimal is 16 which is 16 bytes .
So to understand maximum value possible, I have increased the local packed decimal variable to 16 and was able to see maximum number possible keeping decimals as 9 was huge number - in the help documentation - a formula is provided as well. For easy understanding below screen shot is given.
So above code also support my understanding of 16*2 = 32 numbers possible in which 1 will be taken by +/- sign - which will be 22+9 = 31.
Hope this blog was useful.
You can also read more about predefined numeric type in in help.sap.com
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
4 | |
3 | |
3 | |
2 | |
2 | |
2 | |
2 | |
1 | |
1 | |
1 |