2009-06-01 2 views
9

Я просто укусил следующий сценарий:Почему «**» связывается сильнее, чем отрицание?

>>> -1 ** 2 
-1 

Теперь, копаться в документации Python, it's clear that this is intended behavior, но почему? Я не работаю с любыми другими языками с полномочиями как встроенный оператор, но не имея унарного отрицания как можно более плотно, кажется мне опасным для меня интуитивным.

Есть ли причина, как было сделано таким образом? Схожи ли другие языки с операторами питания?

+1

http://www.wolframalpha.com/input/?i = -1^2 дает -1 То же самое в Mathematica –

+4

Вот почему мне не нравится инфиксная нотация. (expt -1 2) однозначно, как и (- (expt 1 2)). – Svante

+0

Это определенно противоречит интуиции: если знак минуса был между двумя операндами, но как унарный оператор, он должен иметь приоритет (но он никогда не делает, только одна из этих странных вещей). –

ответ

22

Это поведение такое же, как в математических формулах, поэтому я не уверен, в чем проблема, или почему это противоречит интуиции. Можете ли вы объяснить, где вы видели что-то другое? «**» всегда связывает больше, чем «-»: -x^2 не совпадает с (-x)^2

Просто используйте (-1) ** 2, точно так же, как в математике.

+0

@nosklo - Лично я бы не согласился. Обычно я интерпретирую -x^2 как (-x)^2 *, если вы не вычитаете. Итак, 1-x^2 будет 1 + - (x^2) –

+6

@ Джейсон: снова прочитайте свою книгу с пред алгебрами ... это не то, как работает математика. – rmeador

+7

@ Джейсон, вы можете не согласиться, но это стандарт, на который пришли математики. –

3

Если бы я должен был догадаться, это было бы потому, что наличие оператора экспоненциальности позволяет программистам легко поднять числа до дробных степеней. Отрицательные числа, поднятые до дробных степеней, заканчиваются воображаемой составляющей (обычно), поэтому этого можно избежать, связывая ** более плотно, чем унарный. Большинство языков не любят воображаемые числа.

В конечном счете, конечно, это просто соглашение - и чтобы ваш код мог быть прочитан самим и другими людьми по очереди, вы, вероятно, захотите явно сгруппировать свой (-1), чтобы никто не попадал в один и тот же ловушка :) Удачи!

4

Короткий ответ: это стандартный способ приоритета работает в математике.

Скажем, я хочу, чтобы оценить многочлен 3x 3x 2 + 5.

def polynomial(x): 
    return 3*x**3 - x**2 + 5 

Он выглядит лучше, чем ...

def polynomial 
    return 3*x**3 - (x**2) + 5 

И первый путь это путь математики это делают. Другие языки с возвышенностью работают одинаково. Обратите внимание, что оператор отрицания также связывает более свободно, чем умножение, так

-x*y === -(x*y) 

Который также, как они делают это в математике.

+1

Бинарный пример вычитания кажется несущественным. Унарный минус с умножением является более ценным. –

+0

- (x * y) на самом деле то же самое, что и (-x) * y, так что отрицание связывается более или менее свободно, чем умножение на самом деле не совсем ясно (хотя я согласен с вами). Кроме того, @ S.Lott, я не уверен, что математика различает унарные и двоичные ... – weronika

+0

@weronika: они могут быть одинаковыми математически, но они не обязательно одинаковы в компьютерной программе. Например, если вы работаете с 32-битными целыми числами, то '(-0x40000000) * 2' не совпадает с' - (0x40000000 * 2) ', потому что последнее вызывает переполнение. Если ваша среда переполняет ловушки, то только первая правильная. Это также относится к Python, если вы манипулируете 32-битными целыми числами, например. через numpy. –

-1

Ocaml не делает то же самое

# -12.0**2.0 
    ;; 
- : float = 144. 

Это немного странно ...

# -12.0**0.5;; 
- : float = nan 

Посмотрите на эту ссылку, хотя ... order of operations

+2

Ocaml сломан. Это не соответствует этому основному правилу математики. – nosklo

1

кажется интуитивно меня.

Кулак, потому что он согласуется с математическим notaiton: -2^2 = -4.

Во-вторых, оператор ** был широко представлен FORTRAN давным-давно. В ФОРТРАНЕ -2 ** 2 равно -4.

Смежные вопросы