- Se você executar
SELECT -100/-100*10
o resultado é0
. - Se você executar
SELECT (-100/-100)*10
o resultado é10
. - Se você executar
SELECT -100/(-100*10)
o resultado é0
. - Se você executar
SELECT 100/100*10
o resultado é10
.
BOL declara:
Quando dois operadores em uma expressão têm o mesmo nível de precedência de 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)
O BOL está errado ou estou faltando alguma coisa? Parece que o -
está jogando fora a precedência (esperada).
sql
sql-server
tsql
operator-precedence
cuizizhe
fonte
fonte
-
parece estar fazendo com que o fluxo saia "errado". Se você tentar,-100/(-100)*10
obterá o resultado10
. parece que o/
está sendo aplicado contra o valor-
na equação e então a equação100*10
está sendo determinada. Não tenho certeza se isso é um erro com o BOL, mas mais que o SQL Server não está se comportando conforme o esperado. Pode valer a pena levantar um problema em sql-docs e ver qual é a resposta deles; talvez uma nota possa ser adicionada à documentação avisando sobre o "recurso".SELECT -100/(-100)*10
também retorna 10. Parece que-
é tratado como o-
operador que deve ser aplicado somente após100*10
ser calculadoA / -B * C
éA <div> <negate> B <multiply> C
. Negar tem precedência menor do que multiplicar, de acordo com os documentos, então o resultado éA / -(B * C)
. Você pode ver isso mais claramente usando constantes flutuantes:12e / -13e * 14e
vs.12e / (-13e) * 14e
vs.12e / 13e * 14e
O motivo pelo qual isso nos confunde é porque geralmente esperamos que o menos unário se torne parte do literal, ou pelo menos tenha uma precedência muito alta, mas não é assim que o T-SQL trabalho.Respostas:
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:é avaliado como:
Observe que esse comportamento é diferente da maioria das linguagens de programação onde a negação unária tem precedência mais alta do que a multiplicação e divisão, por exemplo , VB , JavaScript .
fonte
-
é considerado um operador em-100
. Em alguns idiomas, faz parte da sintaxe de um inteiro.-
.BOL está correto.
-
tem precedência menor do que*
, entãoé analisado como
Sendo a multiplicação o que é, você normalmente não percebe isso, exceto ao misturar os dois outros operadores binários com igual precedência:
/
e%
(e%
raramente é usado em expressões compostas como esta). assimÉ analisado como
explicando os resultados. Isso é contra-intuitivo porque na maioria das outras linguagens, menos unário tem precedência mais alta do que
*
e/
, mas não em T-SQL, e isso está documentado corretamente.Uma boa (?) Maneira de ilustrar:
produz um estouro aritmético, porque
-(1073741824 * 2)
produz2147483648
como um intermediário, que não cabe em umINT
, masproduz o resultado esperado
-2147483648
, que o faz.fonte
-
é "negativo". Pessoas que dizem coisas como "menos 10" quando querem dizer "10 negativo" estão sendo imprecisas.-
operador, quando aplicado a um único operando, é chamadoMINUS
nos planos de consulta SQL. Sua contraparte binária é chamadaSUB
. Se quiser, interprete "menos unário" como uma abreviação para "o operador unário representado pelo sinal de menos" - uma designação sintática em vez de semântica.Observe na documentação que (talvez contra-intuitivamente) a ordem de precedência para
- (Negative)
é a terceira.Então você efetivamente obtém:
-(100/-(100*10)) = 0
Se você colocá-los em variáveis, não verá isso acontecer, pois não há nenhuma operação unária que ocorre após a multiplicação.
Portanto, aqui A e B são iguais, enquanto C, D, E mostram o resultado que você está vendo (com E tendo o suporte completo)
fonte