Подтвердить что ты не робот

Странный результат вычисления

почему d не равен b в этом примере?

  unsigned int z = 176400;
  long a = -4;
  long b = a*z/1000; //b=4294261
  long c = a*z; // c=-705600
  long d = c/1000; // d =-705

Я использую Visual Studio 2008, Windows XP, Core2duo. Спасибо.

4b9b3361

Ответ 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.