SQL Server의 이상한 작업 문제 : -100 / -100 * 10 = 0


106
  • 실행 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)

BOL이 잘못되었거나 내가 뭔가를 놓치고 있습니까? -(예상 된) 우선 순위를 버리는 것 같습니다 .


7
질문이 뭐야?
Ilyes

14
왜 비트와 관련이 있다고 생각합니까? 당신은 정수로 작업하고 있습니다. 그리고 정수 / 정수 = 정수. 따라서 -100 / -1000은 0입니다
sepupic

5
좋아요, 동의 -합니다. 이로 인해 흐름이 "잘못"되는 것 같습니다. 시도 -100/(-100)*10하면 결과를 얻을 수 있습니다 10. 이 보인다 /값에 대해 적용되는 -식으로 다음 식을 100*10결정하고있다. 이것이 BOL의 오류인지 확실하지 않지만 SQL Server가 예상대로 작동하지 않는 것이 더 많습니다. sql-docs 에서 문제를 제기 하고 응답 내용을 확인하는 것이 좋습니다. 아마도 "기능"에 대해 조언하는 메모가 문서에 추가 될 수 있습니다.
Larnu

3
SELECT -100/(-100)*10또한 10을 반환합니다. 계산 된 후에 만 적용되어야 -하는 -연산자 로 취급되는 것처럼 보입니다.100*10
Panagiotis Kanavos

7
A / -B * C입니다 A <div> <negate> B <multiply> C. Negate는 문서별로 곱하기보다 우선 순위가 낮으므로 결과는 A / -(B * C). 당신은 부동 상수를 사용하여 더 명확하게 볼 수 있습니다 12e / -13e * 14e대를 12e / (-13e) * 14e12e / 13e * 14e이 떨어져 우리를 던졌습니다 우리가 일반적으로 단항 마이너스 리터럴의 일부가 될 것으로 예상하기 때문이다 국지적 인 이유, 또는 적어도 매우 높은 우선 순위를 가지고 있지만, 그 방법 T-SQL이 아니다 공장.
Jeroen Mostert 2019

답변:


96

우선 순위 테이블에 따르면,이 입니다 예상되는 동작. 우선 순위가 더 높은 연산자 ( /*)는 우선 순위가 낮은 연산자 (단항 -) 보다 먼저 평가 됩니다. 그래서 이거:

-100 / -100 * 10

다음과 같이 평가됩니다.

-(100 / -(100 * 10))

이 동작은 단항 부정이 곱셈 및 나눗셈보다 우선하는 대부분의 프로그래밍 언어 (예 : VB , JavaScript )와는 다릅니다 .


38
와, T-SQL의 또 다른 보석 기능 :) 버그를 검색하려면 지금 모든 코드를 감사해야합니다.
usr

14
오 이런. 이것은 다양한 PHP 삼항 연산자 버그 bugs.php.net/bug.php?id=61915 보다 더 나쁩니다 . 단항 연산자가 이항 연산자보다 우선 순위가 낮아야한다고 생각하는 정상인은 무엇입니까?
phuclv

12
실제 차이점은 -에서 연산자로 간주 되는지 여부 입니다 -100. 일부 언어에서는 정수 구문의 일부입니다.
Barmar

7
따라서 그것은 단항 우선 순위의 버그입니다 -.
Kevin

4
그리고 반 직관적 디자인의 우승자는 ...입니다 : Microsoft는 - 한 번 더
rexkogitans

34

BOL이 맞습니다. -보다 우선 순위가 낮 *으므로

-A * B

다음과 같이 구문 분석됩니다.

-(A * B)

: 곱셈 그것이 무엇인지되고, 일반적으로 동일한 우선 순위가 다른 두 이항 연산자에 혼합하는 경우를 제외하고,이 통지를하지 않습니다 /%(과 %거의 같은 화합물 표현식에서 사용되지 않습니다). 그래서

C / -A * B

다음과 같이 구문 분석됩니다.

C / -(A * B)

결과를 설명합니다. 대부분의 다른 언어에서 단항 마이너스가 *및 보다 우선 순위가 높지만 /T-SQL에서는 그렇지 않기 때문에 이것은 직관적이지 않습니다.

그것을 설명하는 좋은 (?) 방법 :

SELECT -1073741824 * 2

에 맞지 않는 중간으로 -(1073741824 * 2)생성 하기 때문에 산술 오버플로를 생성 하지만2147483648INT

SELECT (-1073741824) * 2

예상되는 결과를 생성합니다 -2147483648.


"마이너스"는 바이너리입니다. 단항 -은 "음수"입니다. "음수 10"을 의미 할 때 "마이너스 10"과 같이 말하는 사람들은 부정확합니다.
누적

11
@Acccumulation : 부정확성은 내 것이 아닙니다. -하나의 피연산자에 적용 할 때 연산자,라고 MINUSSQL 쿼리 계획에. 이진 대응 물은 SUB. 원하는 경우 "단항 마이너스"를 "마이너스 기호로 표시되는 단항 연산자"(의미 적 지정이 아닌 구문)의 약자로 해석하십시오.
Jeroen Mostert 2019

3
"네거티브 10"은 미국의 표준 사용 (내 생각에)이지만 영국에서는 표준이 아닙니다.
Alchymist

12

문서에서 (아마도 직관에 반하는) 우선 순위 - (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
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.