Um problema de operação estranha no SQL Server(-100/-100*10=0)




sql-server tsql (2)

  • Se você executar SELECT -100/-100*10 o resultado será 0 .
  • Se você executar SELECT (-100/-100)*10 o resultado será 10 .
  • Se você executar SELECT -100/(-100*10) o resultado será 0 .
  • Se você executar SELECT 100/100*10 o resultado será 10 .

BOL afirma:

Quando dois operadores em uma expressão têm o mesmo nível de precedência do operador, eles são avaliados da esquerda para a direita com base em sua posição na expressão.

E

Level   Operators
  1     ~ (Bitwise NOT)
  2     * (Multiplication), / (Division), % (Modulus)
  3     + (Positive), - (Negative), + (Addition), + (Concatenation), - (Subtraction), & (Bitwise AND), ^ (Bitwise Exclusive OR), | (Bitwise OR)

BOL está errado, ou estou faltando alguma coisa? Parece que o - está jogando fora a precedência (esperada).


BOL está correto. - tem precedência menor que * , então

-A * B

é analisado como

-(A * B)

Sendo a multiplicação o que é, você normalmente não percebe isso, exceto quando mistura os outros dois operadores binários com precedência igual: / e % (e % raramente é usado em expressões compostas como esta). assim

C / -A * B

É analisado como

C / -(A * B)

explicando os resultados. Isso é contra-intuitivo porque na maioria das outras linguagens, unário menos tem precedência mais alta que * e / , mas não em T-SQL, e isso é documentado corretamente.

Um bom (?) Caminho para ilustrar isso:

SELECT -1073741824 * 2

produz um estouro aritmético, porque -(1073741824 * 2) produz 2147483648 como um intermediário, que não se encaixa em um INT , mas

SELECT (-1073741824) * 2

produz o resultado esperado -2147483648 , o que faz.


De acordo com a tabela de precedência, esse é o comportamento esperado. O operador com maior precedência ( / e * ) é avaliado antes do operador com menor precedência (unário - ). Então, é isso:

-100 / -100 * 10

é avaliado como:

-(100 / -(100 * 10))

Note que este comportamento é diferente da maioria das linguagens de programação onde a negação unária tem maior precedência do que multiplicação e divisão, por exemplo, VB , JavaScript .





operator-precedence