Why I started writing a blog
After having explained to one of my younger colleagues why his calculations in a custom condition routine (function group V61A, to be precise) were always a factor 1000 to large, another colleague (thanks René van Mil) of mine came up with the idea to write a series of blogs about old, strange, funny or otherwise quirky ABAP-stuff that most ABAP-programmers will encounter sooner or later. In his opinion, I am the right person for this job, having worked as an ABAP-per since 1989.
So here’s part one (and my first ever blog) about the heritage of ‘fixed point arithmetic’, or rather ‘non-Fixed Point Arithmetic’ code in our current SAP systems. I have some ideas about other subjects, but I’m open to any other idea. Just let me know in your comments.
Calculations in ye olde ABAP days
I started as an ABAP programmer in 1989 with version R/2, 4.2e. For the first 5 years of my ABAP career, this was the user interface I had to work with.
The ABAP language was still in its infancy, with a limited number of statements. For example, the only type of procedure was the subroutine (FORM). Function Modules didn’t exist yet, so the reuse of ABAP code was restricted to the use of external subroutine calls.
Another characteristic of this old ABAP version was that the option ‘ Fixed Point Arithmetic’ was not available yet as an ABAP attribute. The built-in data type ‘Packed’ already existed. However, multiplying or dividing packed fields with decimals was a little bit cumbersome, because the decimal positions were not taken into account during calculations.
Multiplying and dividing with decimals in a non-Fixed Point Arithmetic ABAP
Just consider the following example that you can still check in your current SAP-system:
DATA: a_packed_field TYPE P DECIMALS 2 VALUE ‘100.00’,
another_packed_field TYPE P DECIMALS 2 VALUE ‘200.00’,
the_result_field TYPE P DECIMALS 2.
the_result_field = a_packed_field * another_packed_field.
You would expect the_result_field to contain the value ‘20000.00’. However, without Fixed Point Arithmetic, multiplying both fields results in the value ‘2000000.00’, which is a factor 100 too large. This is caused by the fact that for the multiplication, the decimal places are actually ignored: the calculation that is executed is:100000 * 20000 = 200000000.
To solve this problem, dividing the result by the correct number of decimals had to be added to the statement. This is why all calculations with amounts, quantities and other packed fields with decimals looked like this:
the_result_field = a_packed_field * another_packed_field / 100.
When dividing, the reverse problem would occur and the result of the calculation would be a factor 100 too small.
the_result_field = a_packed_field / another_packed_field.
In the division above,the_result_field contains the value ‘0.01’ instead of the expected 0,50. Actually, the result is ‘0.005’, but this is rounded by the system because the_result_field is defined with 2 decimals.
A correct calculation would be:
the_result_field = a_packed_field * 100 / another_packed_field.
It is not hard to imagine that, when calculations got a bit complex, forgetting to multiply or divide by the correct number of decimal places could lead to very large or very small incorrect numbers. Just consider calculations containing both multiplications and divisions using different numbers of decimal positions, where the result field was defined with yet another number of decimals.
The introduction of the fixed point arithmetic option
I’m not really sure in which R/2 version the ABAP-attribute ‘Fixed Point Arithmetic’ was introduced. As a result, the programming of calculations in new programs got a lot easier. Making the existing programs ‘Fixed Point’-proof was not a very complex task, but a bit boring because it involved checking every calculation and delete the ‘ * 1000’ or ‘/ 1000’ part of it. A lot of companies were understandably not eager to start an ABAP-conversion project, because of a business case was lacking. That’s why it was often decided that an ABAP-conversion could wait until it could be combined with a functional change.
Standard SAP programs were also not changed directly or not at all. And even today, in ECC6.0, Enhancement Pack 6, there are still several much used SAP programs for which the Fixed Point Arithmetic attribute hasn’t been set.
ECC6.0 examples of non-Fixed Point Arithmetic programs
In our ECC6.0 system, there are still 5569 reports, module pools and function groups for which the ‘Fixed Point Arithmetic’ attribute has not been set. There are some programs that you may already have encountered or that you are likely to encounter if you are an ABAP-programmer working on an ECC-system.
Two typical examples of SAP-programs that you might run into are:
- RVADOR01 – Print Program for Sales Documents. This program is often copied to a Z-version (why copying SAP standard is a bad practice deserves a discussion of its own!) and then adapted. It is still being used to print SAPscript, SMARTform or ADOBE forms.
- Function group ‘V61A’- ‘Functions for Pricing’. This function group contains several types of user-exits and enhancements, and user routines for custom conditions, typically called ‘RV61A9..’.
If you change, enhance or otherwise re-use these ABAP-sources, you have to take into account that the attribute ‘Fixed Point Arithmetic’ is not set. Your calculations must be programmed accordingly. An option to overcome this is to delegate the calculations to new custom classes or functions.
You now know that, if the results of multiplications or divisions in a new or changed program are too large or too small by a factor 100 or 1000 or even more, first check the attributes of this program. Maybe it is suffering from ‘Non-Fixed Point Arithmetic’s.