4
votes

I've ran into an issue here, and I can't figure out exactly what SAP is doing. The test is quite simple, I have two variables that are a completely different type as well as having two completely different values.

The input is an INT4 of value 23579235. I am testing the equality function against a string '23579235.43'. Obviously my expectation is that these two variables are different because not only are they not the same type of variable, but they don't have the same value. Nothing about them is similar, actually.

EXPECTED1 23579235.43   C(11)   \TYPE=%_T00006S00000000O0000000302
INDEX1    23579235      I(4)    \TYPE=INT4

However, cl_abap_unit_assert=>assert_equals returns that these two values are identical. I started debugging and noticed the 'EQ' statement was used to check the values, and running the same statement in a simple ABAP also returns 'true' for this comparison.

analysis_Svc=>is_Equal

What is happening here, and why doesn't the check fail immediately after noticing that the two data types aren't even the same? Is this a mistake on my part, or are these assert classes just incorrect?

report ztest.
if ( '23579235.43' eq 23579235 ).
  write: / 'This shouldn''t be shown'.
endif.

whydoesthiswork

1
abap has a number of conversion rules for data types. You're probably seeing one of them in action, the "listen, I know this is a string, but I want it to be treated as a number, please" rule. In todays world an absolute no-go, but from the perspective of 80s business programming a very convenient function. help.sap.com/doc/abapdocu_751_index_htm/7.51/en-US/… - Dirk Trilsbeek

1 Answers

6
votes

As @dirk said, ABAP implicitly converts compared or assigned variables/literals if they have different types.

First, ABAP decides that the C-type literal is to be converted into type I so that it can be compared to the other I literal, and not the opposite because there's this priority rule when you compare types C and I : https://help.sap.com/http.svc/rc/abapdocu_752_index_htm/7.52/en-US/abenlogexp_numeric.htm#@@ITOC@@ABENLOGEXP_NUMERIC_2

               | decfloat16, decfloat34 | f | p | int8 | i, s, b |
.--------------|------------------------|---|---|------|---------|
| string, c, n | decfloat34             | f | p | int8 | i       |

(intersection of "c" and "i" -> bottom rightmost "i")

Then, ABAP converts the C-type variable into I type for doing the comparison, using the adequate rules given at https://help.sap.com/http.svc/rc/abapdocu_752_index_htm/7.52/en-US/abenconversion_type_c.htm#@@ITOC@@ABENCONVERSION_TYPE_C_1 :

Source Field Type c -> Numeric Target Fields -> Target  :
  "The source field must contain a number in mathematical or 
  commercial notation. [...] Decimal places are rounded commercially 
  to integer values. [...]"

Workarounds so that 23579235.43 is not implicitly rounded to 23579235 and so the comparison will work as expected :

  • either IF +'23579235.43' = 23579235. (the + makes it an expression i.e. it corresponds to 0 + '23579235.43' which becomes a big Packed type with decimals, because of another rule named "calculation type")
  • or IF conv decfloat16( '23579235.43' ) = 23579235. (decfloats 16 and 34 are big numbers with decimals)