Странная проблема работы в SQL Server (-100 / -100 * 10 = 0) - PullRequest
0 голосов
/ 04 февраля 2019
  • Если вы выполните SELECT -100/-100*10, результат будет 0.
  • Если вы выполните SELECT (-100/-100)*10, результат будет 10.
  • Если вы выполните SELECT -100/(-100*10)результат будет 0.
  • Если вы выполните SELECT 100/100*10, результат будет 10.

BOL , состояния:

Когда два оператора в выражении имеют одинаковый уровень приоритета операторов, они оцениваются слева направо на основе их положения в выражении.

И

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

IsBOL неправильно, или я что-то упустил?Похоже, что - отбрасывает (ожидаемый) приоритет.

Ответы [ 3 ]

0 голосов
/ 04 февраля 2019

BOL правильно.- имеет более низкий приоритет, чем *, поэтому

-A * B

анализируется как

-(A * B)

Умножение, являющееся тем, чем оно является, вы обычно не замечаете этого, кроме случаев, когда смешиваетев двух других бинарных операторах с равным приоритетом: / и %% редко используется в составных выражениях, подобных этому).Итак,

C / -A * B

Анализируется как

C / -(A * B)

, объясняя результаты.Это нелогично, потому что в большинстве других языков унарный минус имеет более высокий приоритет, чем * и /, но не в T-SQL, и это правильно задокументировано.

Хороший (?) Способчтобы проиллюстрировать это:

SELECT -1073741824 * 2

производит арифметическое переполнение, потому что -(1073741824 * 2) производит 2147483648 как промежуточное звено, которое не помещается в INT, но

SELECT (-1073741824) * 2

выдает ожидаемый результат -2147483648, что и делает.

0 голосов
/ 04 февраля 2019

Обратите внимание, что в документации (возможно, нелогично) порядок старшинства для - (Negative) является третьим.

Таким образом, вы фактически получаете:

-(100/-(100*10)) = 0

Если вы поместите их в переменные, вы не увидите, что это происходит, поскольку после умножения не происходит унарной операции.

Так что здесь A и B одинаковы, тогда как C, D, E показываютрезультат, который вы видите (когда E имеет полный брекетинг)

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
0 голосов
/ 04 февраля 2019

Согласно таблице приоритетов, является ожидаемым поведением.Оператор с более высоким приоритетом (/ и *) оценивается перед оператором с более низким приоритетом (унарный -).Итак, это:

-100 / -100 * 10

оценивается как:

-(100 / -(100 * 10))

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

...