ABAP Keyword Documentation → ABAP − Reference → Processing Internal Data → Numeric Calculations → arith_exp - Arithmetic Expressions
arith_exp - Calculation Type and Calculation Rules
An arithmetic expression is assigned a calculation type that specifies the calculation rules for the expression. The calculation type is determined at program runtime from those data types involved that can be identified. The calculation type only needs to be determined statically if the target field is an inline declaration, where generically type operands are included using a standard type.
Other versions: 7.31 | 7.40 | 7.54
Determining the Calculation Type
The calculation type corresponds to one of the numeric data types i
,
int8, p
, f
, or decfloat34
. It is determined according to the following hierarchy, and in this order of priority:
decfloat16
or decfloat34
, the calculation type is decfloat34
.
f
or if the operator **
is used, the calculation type is f
.
p
, the calculation type is p
.
int8
, the calculation type is int8
.
i
, (b
or s
), the calculation type is i
.
The data type that has the largest value range therefore determines the calculation type. An exception to this is that each
decimal floating point number
produces the calculation type decfloat34
, and that using the operator **
is handled like a data type of type f
.
Involved data types include:
- The right side of an assignment in arithmetic expressions:
- If it is not an inline declaration
DATA(var)
, the data types of all operands of the full arithmetic expressions, and the data type of the result fieldresult
.
- If
result
is an inline declaration, the calculation type derived from the data types of the arithmetic expression determines the data type of the declared variable. Here, a calculation typep
always produces the data typep
with length 8 and no decimal places.
- as the operand of a relational expression in an arithmetic expression, the data types of all operands of the entire relational expression. The approach taken does not involve first determining the calculation type of each arithmetic expression in question and then deriving the comparison type. All operands of the relational expression are used to determine the calculation type (which is also the comparison type) regardless of the arithmetic expressions they belong to.
- in an arithmetic expression after the statement
CASE
, the operands of the arithmetic expression, ignoring the operands specified afterWHEN
.
- as actual parameters for input parameters of methods in an arithmetic expression, the data types of all operands of the whole arithmetic expression and the typing of the formal parameter, provided that it is fully typed. If the formal parameter is typed generically, then only the operands of the expression are evaluated.
- as actual parameters for input parameters of function modules, the data types of all operands of the entire arithmetic expression. The typing of the formal parameter is ignored.
- as an argument of a built-in function in an arithmetic expression, the data types of all operands of the entire arithmetic expression and the type of the input parameter, if determined in full. An overloaded numeric function containing an arithmetic expression as an argument, on the other hand, operates like an arithmetic operator and is handled in its position like an arithmetic expression.
- as an embedded expression in a string template in an arithmetic expression, only the operands of the expression are evaluated.
- as an argument in a constructor expression in an arithmetic expression, the calculation type is determined as in an
assignment. The left side of the assignment is
either the result of the constructor expression with the type
type
specified in front of the parentheses or a structure component.
For operands with complete numeric data types, this data type is used. Operands with other data types are handled as follows:
d
andt
asi
c
,n
, andstring
asp
x
andxstring
asi
utclong
is not allowed
In the case of operands not specified as data objects, the type is determined as follows:
- In the case of operands specified as non-overloaded integrated functions, the data type of the return value applies.
- Operands belonging to overloaded general numeric
functions, and to the overloaded power function
ipow
, are used to determine the calculation type.
- When a floating point function is used, the calculation type is either
decfloat34
orf
.
- In the case of operands specified as functional method calls, the data type of the return value applies.
- In the case of operands specified as constructor
expressions, the data type specified by
type
here applies. The arithmetic expression itself, however, does not determine the type of the constructor expression. If constructor expressions are used as operands of arithmetic expressions, the#
character can only be specified for the data type of the constructor expression if the type can be determined from the constructor expression itself.
- In the case of operands specified as table expressions, the data type of the result applies.
- If operands are specified as generically typed field symbols or formal parameters and an existing variable is used as the target field of an assignment, these operands (together with the data type) contribute to the calculation type assigned to them at runtime.
- If operands are specified as generically typed field symbols or formal parameters and an inline declaration
DATA(var)
is used as the target field of an assignment, the generic types contribute to the statically known calculation type (used to determine the data type of the declaration) as follows.
any
,data
,simple
,numeric
, anddecfloat
likedecfloat34
csequence
,clike
,c
,n
, andp
andp
. If there is no involved type with a greater priority, typep
with length 8 without decimal places is used for the declaration.
xsequence
andx
likei
Notes
- The way a calculation type is identified before the calculation and respecting all operands including the result field (as the right side of an assignment or as an actual parameter in the case of an arithmetic expression) is a special ABAP feature that differs considerably from the way in which other programming languages perform calculations. To avoid unnecessary conversions, all operands and one result field should have the same numeric data type.
- In the case of arithmetic expressions used as operands of
relational expressions in
logical expressions joined using
Boolean operators,
the rule above only ever applies to the relational expression in question. The calculation type is not
determined while skipping the Boolean operators
AND
,OR
, orEQUIV
.
- If the calculation type is
f
, the accuracy is only approximately 15 places and integers are only represented accurately up to an absolute value of 2**53 (that is, 9,007,199,254,740,992). Other subtotals are rounded. This is especially important when using the operator**
, which can produce the calculation typef
if no decimal floating point number is involved.
- To stop the operator
**
producing the calculation typef
, the built-in functionipow
can be used for integer exponents. Here, the calculation type is determined by the argument.
- The time stamp type
utclong
cannot be converted implicitly to a numeric type, and therefore cannot be specified directly as an operand of an arithmetic expression.
- The conversion operator
CONV
can be used to convert parts of arithmetic expressions to other types and hence modify the calculation type.
- A calculation type
p
in assignments to an inline declaration can produce the data typep
with length 8 and no decimal places and this can produce unexpected results and raise exceptions. It is best to either avoid inline declarations when using the calculation typep
or to determine the data type by applying the conversion operatorCONV
to the arithmetic expression.
Example
The calculation type of the following arithmetic expression is f
. Accordingly, for the inline declaration, a data object of the type f
is declared.
DATA(result) = 2 ** 10.
DESCRIBE FIELD result TYPE DATA(t).
cl_demo_output=>display( |{ result } of type { t }| ).
Calculation Rules for Calculation Type
Before the calculation is made, all operands (where this is required) are converted to the calculation type, in accordance with the conversion rules for elementary data types.
The calculation type determines the calculation method and the calculation accuracy:
- Calculation types
i
andint8
The arithmetic expression is calculated using integer arithmetic, in which each subtotal that is not an integer (after a division) is rounded commercially to the nearest integer. Each subtotal must fall within the value range of the data typei
orint8
, otherwise the handleable exception CX_SY_ARITHMETIC_OVERFLOW is raised.
- Calculation type
p
Fixed point arithmetic The arithmetic expression is calculated to an internal accuracy of 31 places and using a special decimal floating point arithmetic for subtotals. During the calculation, the decimal point for numbers of typep
is not fixed. If an overflow occurs because an subtotal is greater than 10^31 - 1, the whole expression is recalculated to an internal accuracy of 63 places, or a maximum value of 10^63 -1 for subtotals. If another overflow occurs, this triggers the treatable exception CX_SY_ARITHMETIC_OVERFLOW. An overflow always occurs if the level of accuracy is not sufficient for all integral digits before the decimal separator. Surplus decimal places do not raise an exception, but are rounded commercially to the nearest whole number for each subtotal.
- Calculation type
f
The arithmetic expression is calculated using the binary floating point arithmetic of the current platform. Each subtotal must fall within the value range of the data typef
, otherwise the handleable exception CX_SY_ARITHMETIC_OVERFLOW is raised. Since the decimal places of a floating point number are represented internally using a dual fraction, there is not an exact equivalent for every number that can be represented in the decimal system. This can produce rounding errors in the subtotals.
- Calculation type
decfloat34
The arithmetic expression is calculated with decimal floating point arithmetic according to norm IEEE-754-2008, where (as for all calculation types) division by 0 does not result in an exception if the dividend is 0. Each subtotal must fall within the value range of the data typedecfloat34
, otherwise the handleable exception CX_SY_ARITHMETIC_OVERFLOW is raised. Subtotals are rounded commercially to the nearest whole number. The scaling of each subtotal is defined such that the smallest possible exponent is selected if the result is not precise, and the following procedure is used to determine the scaling if the result is precise:
- For addition and subtraction, the exponent of the result is the smaller of the exponents of the two operands.
- For multiplication, the exponent of the result is the sum of the exponents of the two operands.
- For division, the exponent of the result is the difference between the exponents of the dividend and of the divisor.
- If the
sqrt
function is used, the exponent is the integer part of half of the exponent of the operand.
Note
Commercial rounding of subtotals in the calculation types i
, int8
,
p
, and decfloat34
is a characteristic that distinguishes
ABAP greatly from other programming languages where the decimal places are usually cut off rather than
rounded. This can produce different results, in particular in divisions with the calculation types i
.
Example
The result of the second arithmetic expression is 0. The calculation type is i
and the subtotals of each division are rounded to 0. The result of the second arithmetic expression is 0.9999999999999999999999999999999999. The calculation type decfloat34
and the subtotals 0.3333333333333333333333333333333333 are not rounded.
The outer conversion operator CONV
creates the integer 1 from this data.
DATA(result1) = 1 / 3 + 1 / 3 + 1 / 3.
DATA(result2) = CONV i( CONV decfloat34( 1 / 3 + 1 / 3 + 1 / 3 ) ).
cl_demo_output=>display( |{ result1 }, { result2 }| ).
Handling the Result
After the calculation is performed, the result of the arithmetic expression is handled as follows:
- In the case of an arithmetic expression as the right side of an assignment statement, the result is converted to the data type of the result field if the calculation type is different.
- With an arithmetic expression on the right side of an
assignment to an inline declaration
DATA(var)
, the statically identifiable calculation type of variablevar
, whereby generically typed field symbols and formal parameters are included with the standard type described above. In the case of the calculation typep
, the data type of the declared variable is alwaysp
with the length 8 without decimal places.
- In the case of an arithmetic expression as an operand of a relational expression, no conversion takes place, since the calculation type and the comparison type are identical.
- In the case of an arithmetic expression used as an actual parameter for input values of methods,
and if the formal parameter is fully typed, the result is converted into the formal parameter type in
the static method call and passed. If the formal parameter is generically typed, it takes on the calculation
type; in the case of calculation type
p
, the number of decimal places is determined based on the accuracy required in the calculation.
Example
Calculation type f
of the following arithmetic expression is
converted to string
, whereby the value is prepared in
scientific notation.
After the assignment, the text string contains the character string 1.0240000000000000E+03.
DATA result TYPE string.
result = 2 ** 10.
cl_demo_output=>display( result ).