| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Общие вопросы по .NET и C# > x ^= y ^= x ^= y; |
| Автор: kurzon 20.9.2007, 12:59 | ||
Ето побитное додавание с права на ливо Пачему компилятор выводит: x=0; y=1984; Обсянить поподробней? |
| Автор: ivashkanet 20.9.2007, 13:29 |
kurzon, извини пожалуйста, но в подобной белиберде сам разбирайся. Неужели тяжело было разбить то же самое на несколько строчек? |
| Автор: Sartorius 20.9.2007, 13:50 | ||||
Кста, при разбиении все работает корректно.
kurzon, посмотри что в MSIL получается |
| Автор: tol05 20.9.2007, 14:26 | ||||||
а что удивляться? Строка
это не
это
т.е. , если в числах, x = 1984 ^(2001^(1984^2001)); или x = 1984 ^ 1984; |
| Автор: Sartorius 20.9.2007, 14:38 | ||
tol05,
Это почему? Посмотри хотя бы на то, что в приведенном тобой выражении значение y не меняется. |
| Автор: Freak_FB 20.9.2007, 15:43 | ||||
Известен метод обмена значениями двух переменных. Но работало это в C++, компилятор которого трактует такой бред иначе, чем компилятор C#.
|
| Автор: W4FhLF 20.9.2007, 15:47 |
| Ага, этот метод когда-то популяризировал Крис Касперски в журнале Хакер, вот и подхватили, хотя я в нём никаких достоинств не вижу. |
| Автор: Sartorius 20.9.2007, 16:07 | ||
видно что компилятор сохраняет первоночальное значени x и когда дело доходит до последнего (левого) ^= использует его. А в y - уже старое значение x. Вот и 0 ЗЫ еще один пример того, что короткая запись совсем не обязательно лучшая |
| Автор: tol05 20.9.2007, 18:56 |
| я проверил еще раз все, что написал. Все верно. Но что значит "приведенном тобой выражении значение y не меняется"? Просто пример я упростил до такого вида. Мог бы написать у = y^(x ^ y) x = x ^у тогда бы у менялась? дела это не меняет и лезть в скомпилированный код ради этого не нужно. Операции имеют приоритет и порядок выполнения (слева-направо или справа-налево). В данном случае результат объясним, а каким образом, через x или через y .... Результат все равно не изменит |
| Автор: kurzon 20.9.2007, 19:45 | ||||
Ето побитное додавание, пачему другой результат, если побитно додавать то результат будет такойже как и по обычном додавать... Добавлено через 7 минут и 49 секунд
Пачему x=0 Но никак не пойму, обяснить? Я думал по механизму етому x=x+y; |
| Автор: tol05 20.9.2007, 20:58 | ||||
это поразрядное исключающее или. Ставит единицы в разрядах, который не совпадают. А если два числа совпадают, то в результате одни нули.
по приведенному ассемблеру я вижу другое... Но спорить не хочу. Не люблю длинных топиков x = 1984 ^(2001^(1984^2001)); давайте сверим это с ассемблером (как принято выражаться "любезно предоставленным нам Sartorius") 00000017 mov edi,7C0h // в edi помещенo 1984 int y = 2001; // (0x7d1) 0000001c mov ebx,7D1h //в edi помещен x, в еbx - y (в еbx помещено 2001) x ^= y ^= x ^= y; 00000021 mov esi,edi // зачем-то сохраняем х в еsi 00000023 xor edi,ebx // в edi помещенo 1984^2001 это 17 00000025 xor ebx,edi // теперь в ebx(y) старое значение X нет (edi изменен) помещаем в ebx 2001^17 это 1984 00000027 xor esi,ebx // обнуляем esiнет (ebx изменен) помещаем в esi 1984^1984 это 0!!! //первый 1984 - это старый х, а второй 1984 - результат предыдущей строки 00000029 mov edi,esi //и сохраняем это в х (0 помещаем в x) ну дальше рассмотрен вариант Sartorius, тут действительно все ясно что скажете? |
| Автор: ivashkanet 21.9.2007, 09:18 | ||||||
Я тут ошибся. Дело в x-е. При подходе к последнему выражению (самому внешнему) x изменился (стал 2001), но используется его изначальное значение (1994)... В подтверждении моих слов следующий код отрабатывает корректно:
А все из-за того, что в двухстрочном варианте в качестве х берётся его новое значение, а не старое как в однострочном... Добавлено @ 09:33
Строки 27 и 29 показывают, что комп достаёт ранее сохранённое в esi значение, производит над ним xor со значением y и сохраняет в x (edi) |
| Автор: kurzon 21.9.2007, 19:29 |
| А как переколировать в асемблер? |