Ответ 1
Похоже, вы используете платформу, где int
и long
имеют одинаковый размер. (Я предположил это тем, что если long
смог удерживать все допустимые значения unsigned int
, вы не увидите поведение, которое вы видите.)
Это означает, что в выражении a*z
оба a
и z
преобразуются в unsigned long
, а результат имеет тип unsigned long
. (ISO/IEC 14882: 2011, 5 [expr]/9... "В противном случае оба операнда должны быть преобразованы в целое число без знака, соответствующее типу операнда со знаком целочисленного типа." )
c
является результатом преобразования этого выражения из unsigned long
в long
, и в вашем случае это приводит к результату, определенному реализацией (который является отрицательным), поскольку положительное значение a*z
не представляется в подписанном long
. В c/1000
, 1000
преобразуется в long
и long
выполняется деление (каламбур не требуется), что приводит к long
(что бывает отрицательным) и сохраняется в d
.
В выражениях a*z/1000
, 1000
(выражение типа int
) преобразуется в unsigned long
, а деление выполняется между двумя unsigned long
, что приводит к положительному результату. Этот результат представляется как long
, и значение не изменяется при преобразовании в long
и сохраняется на b
.