Проверка равенства SAP неверна
Я столкнулся с проблемой здесь, и я не могу точно понять, что делает SAP. Тест довольно прост, у меня есть две переменные совершенно другого типа, а также два совершенно разных значения.
В качестве значения INT4 используется значение 23579235. Я проверяю функцию равенства на строку "23579235.43". Очевидно, я ожидаю, что эти две переменные разные, потому что они не только не того же типа, но и не имеют одинаковое значение. Ничто в них не похоже на самом деле.
EXPECTED1 23579235.43 C(11) \TYPE=%_T00006S00000000O0000000302
INDEX1 23579235 I(4) \TYPE=INT4
Тем не мение, cl_abap_unit_assert=>assert_equals
возвращает, что эти два значения идентичны. Я начал отладку и заметил, что оператор "EQ" использовался для проверки значений, и выполнение того же оператора в простом ABAP также возвращает "true" для этого сравнения.
Что здесь происходит, и почему проверка не проходит сразу же после того, как вы заметили, что два типа данных даже не совпадают? Это ошибка с моей стороны, или эти классы утверждений просто неверны?
report ztest.
if ( '23579235.43' eq 23579235 ).
write: / 'This shouldn''t be shown'.
endif.
1 ответ
Как сказал @dirk, ABAP неявно преобразует сравниваемые или назначенные переменные / литералы, если они имеют разные типы.
Во-первых, ABAP решает, что литерал C-типа должен быть преобразован в тип I, чтобы его можно было сравнить с другим литералом I, а не наоборот, потому что при сравнении типов C и I существует это правило приоритета: https://help.sap.com/http.svc/rc/abapdocu_752_index_htm/7.52/en-US/abenlogexp_numeric.htm
| decfloat16, decfloat34 | f | p | int8 | i, s, b |
.--------------|------------------------|---|---|------|---------|
| string, c, n | decfloat34 | f | p | int8 | i |
(пересечение "c" и "i" -> крайний правый "i")
Затем ABAP преобразует переменную типа C в тип I для сравнения, используя соответствующие правила, приведенные на https://help.sap.com/http.svc/rc/abapdocu_752_index_htm/7.52/en-US/abenconversion_type_c.htm:
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. [...]"
Обойти так, чтобы 23579235.43
неявно округляется до 23579235
и так сравнение будет работать как положено:
- или
IF +'23579235.43' = 23579235.
(+ делает это выражением, т.е. оно соответствует0 + '23579235.43'
который становится большим упакованным типом с десятичными числами из-за другого правила, называемого " тип вычисления") - или же
IF conv decfloat16( '23579235.43' ) = 23579235.
(decfloats 16 и 34 - большие числа с десятичными знаками)