2009-06-01 9 views
9

Estaba mordido por el siguiente escenario:¿Por qué "**" se une más fuertemente que la negación?

>>> -1 ** 2 
-1 

Ahora, cavar a través de la documentación de Python, it's clear that this is intended behavior, pero por qué? No trabajo con ningún otro idioma con poder como operador integrado, pero no tener la negación unaria se une tan fuertemente como me parece peligrosamente contra-intuitivo para mí.

¿Hay alguna razón por la que se hizo de esta manera? ¿Se comportan de manera similar otros idiomas con operadores de potencia?

+1

http://www.wolframalpha.com/input/?i = -1^2 rendimientos -1 Es lo mismo en Mathematica –

+4

Es por eso que no me gusta la notación infija. (expt -1 2) no es ambiguo, como es (- (expt 1 2)). – Svante

+0

Definitivamente es contra-intuitivo: no si el signo menos estaba entre dos operandos, pero como operador unario debería tener prioridad (pero nunca lo hace, solo una de esas cosas extrañas). –

Respuesta

22

Ese comportamiento es el mismo que en las fórmulas matemáticas, por lo que no estoy seguro de cuál es el problema o por qué no es intuitivo. ¿Puedes explicar dónde has visto algo diferente? "**" siempre vincula más que "-": -x^2 no es lo mismo que (-x)^2

Simplemente use (-1) ** 2, exactamente como lo haría en matemáticas.

+0

@nosklo - Personalmente, no estoy de acuerdo. Típicamente interpretaré -x^2 como siendo (-x)^2 * a menos que * estés restando. Entonces 1-x^2 sería 1 + - (x^2) –

+6

@Jason: ve a leer tu libro de álgebra nuevamente ... así no es como funcionan las matemáticas. – rmeador

+7

@Jason, puede estar en desacuerdo, pero ese es el estándar que los matemáticos han establecido. –

3

Si tuviera que adivinar, sería porque tener un operador de exponenciación permite a los programadores aumentar fácilmente los números a potencias fraccionarias. Los números negativos elevados a potencias fraccionarias terminan con un componente imaginario (generalmente), de modo que se puede evitar uniendo ** más estrechamente que unario -. A la mayoría de los idiomas no les gustan los números imaginarios.

Al final, por supuesto, es solo una convención, y para hacer que su código sea legible por usted y otros más adelante, probablemente desee agrupar explícitamente (-1) para que nadie más quede atrapado por el mismo trampa :) Buena suerte!

4

Respuesta corta: es la forma estándar en que la precedencia funciona en matemáticas.

Digamos que quiero evaluar el polinomio 3x 3x 2 + 5.

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

Se ve mejor que ...

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

Y el primer camino es el camino los matemáticos lo hacen. Otros lenguajes con exponenciación funcionan de la misma manera. Tenga en cuenta que el operador de negación también se une más débilmente que la multiplicación, por lo

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

que es también la forma en que lo hacen en matemáticas.

+1

El ejemplo de resta binaria parece irrelevante. El ejemplo menos unario con multiplicación es más valioso. –

+0

- (x * y) es de hecho lo mismo que (-x) * y, por lo tanto, si la negación se une de manera más o menos imprecisa que la multiplicación no está clara a partir de esto (aunque estoy de acuerdo con usted). Además, @ S. Lot, no estoy seguro de que las matemáticas distingan entre unario y binario -... – weronika

+0

@weronika: pueden ser las mismas matemáticamente, pero no son necesariamente las mismas en un programa de computadora. Por ejemplo, si está trabajando con enteros de 32 bits, entonces '(-0x40000000) * 2' no es lo mismo que' - (0x40000000 * 2) ', porque este último causa desbordamiento. Si su entorno atrapa el desbordamiento, solo el primero es correcto. Esto también puede aplicarse a Python, si está manipulando enteros de 32 bits, p. a través de numpy. –

-1

Ocaml no hace el mismo

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

Eso es un poco raro ...

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

vistazo a ese enlace, aunque ... order of operations

+2

Ocaml está roto. No sigue esta regla matemática básica. – nosklo

1

Parece intuitivo yo.

Puño, porque es consistente con la notación matemática: -2^2 = -4.

En segundo lugar, el operador ** fue ampliamente introducido por FORTRAN hace mucho tiempo. En FORTRAN, -2 ** 2 es -4, también.

Cuestiones relacionadas