Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 20.10.2012, 10:15
Аватар для Дзен-трансгуманист
√₋̅₁̅
Отправить личное сообщение для Дзен-трансгуманист Посмотреть профиль Найти все сообщения от Дзен-трансгуманист
 
Регистрация: 18.06.2012
Сообщений: 385

XOR swap: ЧЯДНТ?
Нет, я не задрот оптимизации.
Просто мне стало интересно.
var x = 10, y = 20;

x ^= y;
y ^= x;
x ^= y;

alert("x = " + x + ", y = " + y); // Всё ништяк

x = 10; y = 20;

x ^= (y ^= (x ^= y));

alert("x = " + x + ", y = " + y); // WTF???


Аналогичная операция через обычную арифметику:
var x = 10, y = 20;

x += y;
y = x - y;
x -= y;

alert("x = " + x + ", y = " + y); // Всё ништяк

x = 10; y = 20;

x -= (y = (x += y) - y);

alert("x = " + x + ", y = " + y); // И тут та же фигня


Выходит, что и тут и там в самом левом "икс" исходное значение сохраняется вплоть до последней операции, тогда как должно было измениться немедленно при (x ^= y) и (x += y) соответственно.

Это нормально с точки зрения языка?
Если да, то почему, где тут логика, ткните пальцем.

Последний раз редактировалось Дзен-трансгуманист, 20.10.2012 в 10:33.
Ответить с цитированием
  #2 (permalink)  
Старый 20.10.2012, 11:56
sinistral
Посмотреть профиль Найти все сообщения от melky
 
Регистрация: 28.03.2011
Сообщений: 5,418

Сообщение от Дзен-трансгуманист
Выходит, что и тут и там в самом левом "икс" исходное значение сохраняется вплоть до последней операции, тогда как должно было измениться немедленно при (x ^= y) и (x += y) соответственно.
неа

var x = 10, y = 20;

x -= (y = ((x += y), alert("x = " + x), x) - y);


ещё примерчик, без игреков, чтобы было легче усвоить:

x = 3;

x += 3; // x = 6
x -= 9 - x; // 9 - 6 === 3

alert(x);

x = 3;

x -= ( 9 - ( x += 3 ) );

alert(x); // 0


после этого углубляемся в спеку :
  1. Пусть lref будет результатом вычисления LeftHandSideExpression.
  2. Пусть lval будет GetValue(lref).
  3. Пусть rref будет результатом вычисления AssignmentExpression.
  4. Пусть rval будет GetValue(rref).
  5. Пусть r будет результатом применения оператора @ к lval и rval.
  6. Вызвать PutValue(lref, r) и вернуть r.

во втором примере (моём) берётся значение икса (3), далее вычисляется значение правой стороны ( тоже 3), потом честно применяется к ним минус, получаем нуль.

фишка в том, что X изменяется, но двиг уже взял его значение (старое), и не обновляет его (ящитаю)

т.е. в числах всё происходит так :
3 -  (9 -  (3 + 3)); // 3 - (6 - 3) -> 3 - 3.

Последний раз редактировалось melky, 20.10.2012 в 12:25.
Ответить с цитированием
  #3 (permalink)  
Старый 20.10.2012, 12:30
Аватар для nerv_
junior
Отправить личное сообщение для nerv_ Посмотреть профиль Найти все сообщения от nerv_
 
Регистрация: 29.11.2011
Сообщений: 3,924

melky, не перестаешь меня удивлять
Сообщение от melky
ящитаю


Дзен-трансгуманист, думаю, абсолютно нормально. Попробую аргументировать:
x -= (y = (x += y) - y);

присвоение с операцией выполняется следующим образом:
1. сперва вычисляется выражения справа от [B]x -= ...[/B], а затем происходит присвоение
2. т.е. здесь [B]x += y[/B] его быть не может потому, что оно должно произойти позже (после вычисления всего выражения)
3. иными словами [B]x += y[/B] в данном случае работает как [B]x + y[/B]

Это как бы мое мнение не опираясь на спецификацию

Ну а коли речь зашла о нормальности, то подобные конструкции сами по себе ай-яй-яй )
__________________
Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук

Последний раз редактировалось nerv_, 20.10.2012 в 12:32.
Ответить с цитированием
  #4 (permalink)  
Старый 20.10.2012, 12:32
sinistral
Посмотреть профиль Найти все сообщения от melky
 
Регистрация: 28.03.2011
Сообщений: 5,418

Сообщение от nerv_
melky, не перестаешь меня удивлять
мы любим луркмоар
Сообщение от nerv_
Это как бы мое мнение не опираясь на спецификацию
как тебе мой ответ с опором на спецификацию?

Сообщение от nerv_
т.е. здесь x += y его быть не может потому, что оно должно произойти позже (после вычисления всего выражения)
м-м, можно припихнуть туда алерт, и будет видно, что значение икса поменялось (см. мой пост)
Ответить с цитированием
  #5 (permalink)  
Старый 20.10.2012, 13:06
Аватар для nerv_
junior
Отправить личное сообщение для nerv_ Посмотреть профиль Найти все сообщения от nerv_
 
Регистрация: 29.11.2011
Сообщений: 3,924

Сообщение от melky
как тебе мой ответ с опором на спецификацию?
вроде как лучше, чем мой
Сообщение от melky
м-м, можно припихнуть туда алерт, и будет видно, что значение икса поменялось (см. мой пост)
угу
__________________
Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук
Ответить с цитированием
  #6 (permalink)  
Старый 20.10.2012, 17:54
Аватар для x-yuri
Отправить личное сообщение для x-yuri Посмотреть профиль Найти все сообщения от x-yuri
 
Регистрация: 27.12.2008
Сообщений: 4,201

Сообщение от Дзен-трансгуманист
Это нормально с точки зрения языка?
http://lurkmore.to/I%2B%2B
Ответить с цитированием
  #7 (permalink)  
Старый 20.10.2012, 22:07
Аватар для B@rmaley.e><e
⊞ Развернуть
Отправить личное сообщение для B@rmaley.e><e Посмотреть профиль Найти все сообщения от B@rmaley.e><e
 
Регистрация: 11.01.2010
Сообщений: 1,810

Хоть всё уже и расписали, вставлю свои 5 копеек:
Запись вида x ^= y (как и подобные) эквивалентна записи вида x = x ^ y. Понятно, что если во втором операнде, т.е. в выражении y изменяется x, то на первый операнд оно уже не влияет, т.к. тот уже был вычислен.
Ответить с цитированием
  #8 (permalink)  
Старый 21.10.2012, 08:28
Аватар для Дзен-трансгуманист
√₋̅₁̅
Отправить личное сообщение для Дзен-трансгуманист Посмотреть профиль Найти все сообщения от Дзен-трансгуманист
 
Регистрация: 18.06.2012
Сообщений: 385

Ага, всё, теперь вкурил. Значит я просто неверно понимал механизм составного присваивания в JS.)
Спасибо всем.
__________________

Гейзенберг, возможно, читал этот тред.
Ответить с цитированием
  #9 (permalink)  
Старый 24.10.2012, 01:20
Аватар для x-yuri
Отправить личное сообщение для x-yuri Посмотреть профиль Найти все сообщения от x-yuri
 
Регистрация: 27.12.2008
Сообщений: 4,201

Сообщение от B@rmaley.e><e
Запись вида x ^= y (как и подобные) эквивалентна записи вида x = x ^ y. Понятно, что если во втором операнде, т.е. в выражении y изменяется x, то на первый операнд оно уже не влияет, т.к. тот уже был вычислен.
Не всем понятно, см. ссылку выше.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск