Я столкнулся с проблемой здесь, и я не могу точно понять, что делает 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 также возвращает «истина» для этого сравнения.
Что здесь происходит, и почему проверка не заканчивается сразу после того, как вы заметили, что эти два типа данных даже не совпадают? Это моя ошибка или эти классы assert просто неверны?
report ztest.
if ( '23579235.43' eq 23579235 ).
write: / 'This shouldn''t be shown'.
endif.





Как сказал @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#@@ITOC@@ABENLOGEXP_NUMERIC_2
| 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#@@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. [...]"
Обходные пути, чтобы 23579235.43 не был неявно округлен до 23579235 и чтобы сравнение работало должным образом:
IF +'23579235.43' = 23579235. (+ делает его выражением, т. е. соответствует 0 + '23579235.43', который становится большим упакованным типом с десятичными знаками из-за другого правила под названием "тип расчета")IF conv decfloat16( '23579235.43' ) = 23579235. (десятичные числа 16 и 34 - большие числа с десятичными знаками)
abap имеет ряд правил преобразования типов данных. Вы, вероятно, видите одно из них в действии, правило «послушайте, я знаю, что это строка, но я хочу, чтобы она рассматривалась как число, пожалуйста». В современном мире это абсолютно неприемлемо, но с точки зрения бизнес-программирования 80-х - очень удобная функция. help.sap.com/doc/abapdocu_751_index_htm/7.51/en-US/…