Un problema de operación extraño en SQL Server(-100/-100*10=0
sql-server tsql (3)
-
Si ejecuta
SELECT -100/-100*10
el resultado es0
. -
Si ejecuta
SELECT (-100/-100)*10
el resultado es10
. -
Si ejecuta
SELECT -100/(-100*10)
el resultado es0
. -
Si ejecuta
SELECT 100/100*10
el resultado es10
.
BOL estados:
Cuando dos operadores en una expresión tienen el mismo nivel de precedencia de operadores, se evalúan de izquierda a derecha según su posición en la expresión.
Y
Level Operators
1 ~ (Bitwise NOT)
2 * (Multiplication), / (Division), % (Modulus)
3 + (Positive), - (Negative), + (Addition), + (Concatenation), - (Subtraction), & (Bitwise AND), ^ (Bitwise Exclusive OR), | (Bitwise OR)
¿Está BOL equivocado, o me estoy perdiendo algo?
Parece que el
-
está desechando la precedencia (esperada).
BOL es correcto.
-
tiene menor precedencia que
*
, entonces
-A * B
se analiza como
-(A * B)
Dado que la multiplicación es lo que es, normalmente no se nota esto, excepto cuando se mezclan en los otros dos operadores binarios con igual precedencia:
/
y
%
(y
%
rara vez se usa en expresiones compuestas como esta).
Asi que
C / -A * B
Se analiza como
C / -(A * B)
Explicando los resultados.
Esto es contraintuitivo porque en la mayoría de los otros idiomas, el menos unario tiene una prioridad más alta que
*
y
/
, pero no en T-SQL, y esto está documentado correctamente.
Una buena manera de ilustrarlo:
SELECT -1073741824 * 2
produce un desbordamiento aritmético, porque
-(1073741824 * 2)
produce
2147483648
como intermedio, que no cabe en un
INT
, pero
SELECT (-1073741824) * 2
produce el resultado esperado
-2147483648
, que lo hace.
De acuerdo con la tabla de precedencia, este
es
el comportamiento esperado.
El operador con mayor prioridad (
/
y
*
) se evalúa antes que el operador con menor prioridad (unario
-
).
Así que esto:
-100 / -100 * 10
se evalúa como:
-(100 / -(100 * 10))
Tenga en cuenta que este comportamiento es diferente de la mayoría de los lenguajes de programación donde la negación unaria tiene mayor prioridad que la multiplicación y la división, por ejemplo, VB , JavaScript .
Observe en la documentación que (tal vez en forma contraria a la intuición) el orden de precedencia para
- (Negative)
es tercero.
Así que efectivamente obtienes:
-(100/-(100*10)) = 0
Si los coloca en variables, no verá que esto suceda, ya que no hay una operación única que ocurra después de la multiplicación.
Así que aquí A y B son iguales, mientras que C, D, E muestran el resultado que está viendo (con E el corchete completo)
DECLARE @i1 int, @i2 int, @i3 int;
SELECT @i1 = -100,
@i2 = -100,
@i3 = 10;
SELECT @i1/@i2*@i3 [A],
-100/(-100)*10 [B],
-100/-100*10 [C],
-100/-(100*10) [D],
-(100/-(100*10)) [E];
A - 10
B - 10
C - 0
D - 0
E - 0