Quantcast
Channel: ABAP Development
Viewing all articles
Browse latest Browse all 948

Packed Number Simplified!

$
0
0

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 .

image - Copy.jpg

 

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 .

debugger1.jpg

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.


decimal.png


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.

packed decimal max.png


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



Viewing all articles
Browse latest Browse all 948

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>