A strange operation problem in SQL Server (-100/-100*10 = 0)
- If you execute
SELECT -100/-100*10
the result is0
. - If you execute
SELECT (-100/-100)*10
the result is10
. - If you execute
SELECT -100/(-100*10)
the result is0
. - If you execute
SELECT 100/100*10
the result is10
.
BOL states:
When two operators in an expression have the same operator precedence level, they are evaluated left to right based on their position in the expression.
And
Level Operators
1 ~ (Bitwise NOT)
2 * (Multiplication), / (Division), % (Modulus)
3 + (Positive), - (Negative), + (Addition), + (Concatenation), - (Subtraction), & (Bitwise AND), ^ (Bitwise Exclusive OR), | (Bitwise OR)
Is BOL wrong, or am I missing something? It seems the -
is throwing the (expected) precedence off.
sql sql-server tsql operator-precedence
|
show 18 more comments
- If you execute
SELECT -100/-100*10
the result is0
. - If you execute
SELECT (-100/-100)*10
the result is10
. - If you execute
SELECT -100/(-100*10)
the result is0
. - If you execute
SELECT 100/100*10
the result is10
.
BOL states:
When two operators in an expression have the same operator precedence level, they are evaluated left to right based on their position in the expression.
And
Level Operators
1 ~ (Bitwise NOT)
2 * (Multiplication), / (Division), % (Modulus)
3 + (Positive), - (Negative), + (Addition), + (Concatenation), - (Subtraction), & (Bitwise AND), ^ (Bitwise Exclusive OR), | (Bitwise OR)
Is BOL wrong, or am I missing something? It seems the -
is throwing the (expected) precedence off.
sql sql-server tsql operator-precedence
7
What's your question?
– Sami
Feb 4 at 9:45
14
Why do you think you have to do with bits, you are working with integers. And integer/integer = integer. So -100/-1000 is 0
– sepupic
Feb 4 at 9:46
5
OK, I do agree, that-
does seem to be causing the flow to go "wrong". If you try-100/(-100)*10
you get the result10
. it seems that the/
is being applied against to value-
in the equation and then the equation100*10
is being determined. I'm not sure this is an error with BOL, but more that SQL Server isn't behaving as expected. It might be worth raising an issue on sql-docs and seeing what their response is there; perhaps a note could be added to the documentation advising of the "feature".
– Larnu
Feb 4 at 10:24
3
SELECT -100/(-100)*10
also returns 10. It looks like-
is treated as the-
operator which should be applied only after100*10
is calculated
– Panagiotis Kanavos
Feb 4 at 10:25
7
A / -B * C
isA <div> <negate> B <multiply> C
. Negate has lower precedence than multiply, per the docs, so the result isA / -(B * C)
. You can see this more clearly by using floating constants:12e / -13e * 14e
vs.12e / (-13e) * 14e
vs12e / 13e * 14e
.The reason this throws us off is because we generally expect unary minus to become part of the literal, or at least have very high precedence, but that's not how T-SQL works.
– Jeroen Mostert
Feb 4 at 10:36
|
show 18 more comments
- If you execute
SELECT -100/-100*10
the result is0
. - If you execute
SELECT (-100/-100)*10
the result is10
. - If you execute
SELECT -100/(-100*10)
the result is0
. - If you execute
SELECT 100/100*10
the result is10
.
BOL states:
When two operators in an expression have the same operator precedence level, they are evaluated left to right based on their position in the expression.
And
Level Operators
1 ~ (Bitwise NOT)
2 * (Multiplication), / (Division), % (Modulus)
3 + (Positive), - (Negative), + (Addition), + (Concatenation), - (Subtraction), & (Bitwise AND), ^ (Bitwise Exclusive OR), | (Bitwise OR)
Is BOL wrong, or am I missing something? It seems the -
is throwing the (expected) precedence off.
sql sql-server tsql operator-precedence
- If you execute
SELECT -100/-100*10
the result is0
. - If you execute
SELECT (-100/-100)*10
the result is10
. - If you execute
SELECT -100/(-100*10)
the result is0
. - If you execute
SELECT 100/100*10
the result is10
.
BOL states:
When two operators in an expression have the same operator precedence level, they are evaluated left to right based on their position in the expression.
And
Level Operators
1 ~ (Bitwise NOT)
2 * (Multiplication), / (Division), % (Modulus)
3 + (Positive), - (Negative), + (Addition), + (Concatenation), - (Subtraction), & (Bitwise AND), ^ (Bitwise Exclusive OR), | (Bitwise OR)
Is BOL wrong, or am I missing something? It seems the -
is throwing the (expected) precedence off.
sql sql-server tsql operator-precedence
sql sql-server tsql operator-precedence
edited Feb 14 at 9:35
Salman A
184k67343441
184k67343441
asked Feb 4 at 9:43
cuizizhecuizizhe
44447
44447
7
What's your question?
– Sami
Feb 4 at 9:45
14
Why do you think you have to do with bits, you are working with integers. And integer/integer = integer. So -100/-1000 is 0
– sepupic
Feb 4 at 9:46
5
OK, I do agree, that-
does seem to be causing the flow to go "wrong". If you try-100/(-100)*10
you get the result10
. it seems that the/
is being applied against to value-
in the equation and then the equation100*10
is being determined. I'm not sure this is an error with BOL, but more that SQL Server isn't behaving as expected. It might be worth raising an issue on sql-docs and seeing what their response is there; perhaps a note could be added to the documentation advising of the "feature".
– Larnu
Feb 4 at 10:24
3
SELECT -100/(-100)*10
also returns 10. It looks like-
is treated as the-
operator which should be applied only after100*10
is calculated
– Panagiotis Kanavos
Feb 4 at 10:25
7
A / -B * C
isA <div> <negate> B <multiply> C
. Negate has lower precedence than multiply, per the docs, so the result isA / -(B * C)
. You can see this more clearly by using floating constants:12e / -13e * 14e
vs.12e / (-13e) * 14e
vs12e / 13e * 14e
.The reason this throws us off is because we generally expect unary minus to become part of the literal, or at least have very high precedence, but that's not how T-SQL works.
– Jeroen Mostert
Feb 4 at 10:36
|
show 18 more comments
7
What's your question?
– Sami
Feb 4 at 9:45
14
Why do you think you have to do with bits, you are working with integers. And integer/integer = integer. So -100/-1000 is 0
– sepupic
Feb 4 at 9:46
5
OK, I do agree, that-
does seem to be causing the flow to go "wrong". If you try-100/(-100)*10
you get the result10
. it seems that the/
is being applied against to value-
in the equation and then the equation100*10
is being determined. I'm not sure this is an error with BOL, but more that SQL Server isn't behaving as expected. It might be worth raising an issue on sql-docs and seeing what their response is there; perhaps a note could be added to the documentation advising of the "feature".
– Larnu
Feb 4 at 10:24
3
SELECT -100/(-100)*10
also returns 10. It looks like-
is treated as the-
operator which should be applied only after100*10
is calculated
– Panagiotis Kanavos
Feb 4 at 10:25
7
A / -B * C
isA <div> <negate> B <multiply> C
. Negate has lower precedence than multiply, per the docs, so the result isA / -(B * C)
. You can see this more clearly by using floating constants:12e / -13e * 14e
vs.12e / (-13e) * 14e
vs12e / 13e * 14e
.The reason this throws us off is because we generally expect unary minus to become part of the literal, or at least have very high precedence, but that's not how T-SQL works.
– Jeroen Mostert
Feb 4 at 10:36
7
7
What's your question?
– Sami
Feb 4 at 9:45
What's your question?
– Sami
Feb 4 at 9:45
14
14
Why do you think you have to do with bits, you are working with integers. And integer/integer = integer. So -100/-1000 is 0
– sepupic
Feb 4 at 9:46
Why do you think you have to do with bits, you are working with integers. And integer/integer = integer. So -100/-1000 is 0
– sepupic
Feb 4 at 9:46
5
5
OK, I do agree, that
-
does seem to be causing the flow to go "wrong". If you try -100/(-100)*10
you get the result 10
. it seems that the /
is being applied against to value -
in the equation and then the equation 100*10
is being determined. I'm not sure this is an error with BOL, but more that SQL Server isn't behaving as expected. It might be worth raising an issue on sql-docs and seeing what their response is there; perhaps a note could be added to the documentation advising of the "feature".– Larnu
Feb 4 at 10:24
OK, I do agree, that
-
does seem to be causing the flow to go "wrong". If you try -100/(-100)*10
you get the result 10
. it seems that the /
is being applied against to value -
in the equation and then the equation 100*10
is being determined. I'm not sure this is an error with BOL, but more that SQL Server isn't behaving as expected. It might be worth raising an issue on sql-docs and seeing what their response is there; perhaps a note could be added to the documentation advising of the "feature".– Larnu
Feb 4 at 10:24
3
3
SELECT -100/(-100)*10
also returns 10. It looks like -
is treated as the -
operator which should be applied only after 100*10
is calculated– Panagiotis Kanavos
Feb 4 at 10:25
SELECT -100/(-100)*10
also returns 10. It looks like -
is treated as the -
operator which should be applied only after 100*10
is calculated– Panagiotis Kanavos
Feb 4 at 10:25
7
7
A / -B * C
is A <div> <negate> B <multiply> C
. Negate has lower precedence than multiply, per the docs, so the result is A / -(B * C)
. You can see this more clearly by using floating constants: 12e / -13e * 14e
vs. 12e / (-13e) * 14e
vs 12e / 13e * 14e
.The reason this throws us off is because we generally expect unary minus to become part of the literal, or at least have very high precedence, but that's not how T-SQL works.– Jeroen Mostert
Feb 4 at 10:36
A / -B * C
is A <div> <negate> B <multiply> C
. Negate has lower precedence than multiply, per the docs, so the result is A / -(B * C)
. You can see this more clearly by using floating constants: 12e / -13e * 14e
vs. 12e / (-13e) * 14e
vs 12e / 13e * 14e
.The reason this throws us off is because we generally expect unary minus to become part of the literal, or at least have very high precedence, but that's not how T-SQL works.– Jeroen Mostert
Feb 4 at 10:36
|
show 18 more comments
3 Answers
3
active
oldest
votes
According to the precedence table, this is the expected behavior. The operator with higher precedence (/
and *
) is evaluated before operator with lower precedence (unary -
). So this:
-100 / -100 * 10
is evaluated as:
-(100 / -(100 * 10))
Note that this behavior is different from most programming languages where unary negation has higher precedence than multiplication and division e.g. VB, JavaScript.
38
Wow, another gem feature in T-SQL :) I guess I have to audit all of my code now to search for bugs.
– usr
Feb 4 at 14:09
14
oh man. This is even worse than the various PHP ternary operator bugs bugs.php.net/bug.php?id=61915. What sane people think that unary operators must have lower precedence than binary ones?
– phuclv
Feb 4 at 15:22
12
The real difference may be whether-
is considered an operator in-100
. In some languages, it's part of the syntax of an integer.
– Barmar
Feb 4 at 16:57
7
So it's a bug in their precedence of unary-
.
– Kevin
Feb 4 at 17:47
4
And the winner of counter-intuitive design is ...: Microsoft - once more
– rexkogitans
Feb 5 at 7:30
|
show 8 more comments
BOL is correct. -
has lower precedence than *
, so
-A * B
is parsed as
-(A * B)
Multiplication being what it is, you don't typically notice this, except when mixing in the two other binary operators with equal precedence: /
and %
(and %
is rarely used in compound expressions like this). So
C / -A * B
Is parsed as
C / -(A * B)
explaining the results. This is counter-intuitive because in most other languages, unary minus has higher precedence than *
and /
, but not in T-SQL, and this is documented correctly.
A nice (?) way to illustrate it:
SELECT -1073741824 * 2
produces an arithmetic overflow, because -(1073741824 * 2)
produces 2147483648
as an intermediate, which does not fit in an INT
, but
SELECT (-1073741824) * 2
produces the expected result -2147483648
, which does.
"minus" is binary. Unary-
is "negative". People who say things like "minus 10" when they mean "negative 10" are being imprecise.
– Acccumulation
Feb 4 at 18:19
10
@Acccumulation: the imprecision isn't mine. The-
operator, when applied to a single operand, is calledMINUS
in SQL query plans. Its binary counterpart is calledSUB
. If you like, interpret "unary minus" as shorthand for "the unary operator signified by the minus sign" -- a syntactic rather than a semantic designation.
– Jeroen Mostert
Feb 4 at 18:33
3
"negative 10" is standard American usage (I believe) but it is not standard in the UK.
– Alchymist
Feb 5 at 11:11
add a comment |
Notice in the documentation that (perhaps counter-intuitively) the order of precedence for - (Negative)
is third.
So you effectively get:
-(100/-(100*10)) = 0
If you place them into variables you won't see this happening, as there is no unary operation that occurs after the multiplication.
So here A and B are the same, whereas C, D, E show the result you are seeing (with E having the complete bracketing)
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
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54513450%2fa-strange-operation-problem-in-sql-server-100-10010-0%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
According to the precedence table, this is the expected behavior. The operator with higher precedence (/
and *
) is evaluated before operator with lower precedence (unary -
). So this:
-100 / -100 * 10
is evaluated as:
-(100 / -(100 * 10))
Note that this behavior is different from most programming languages where unary negation has higher precedence than multiplication and division e.g. VB, JavaScript.
38
Wow, another gem feature in T-SQL :) I guess I have to audit all of my code now to search for bugs.
– usr
Feb 4 at 14:09
14
oh man. This is even worse than the various PHP ternary operator bugs bugs.php.net/bug.php?id=61915. What sane people think that unary operators must have lower precedence than binary ones?
– phuclv
Feb 4 at 15:22
12
The real difference may be whether-
is considered an operator in-100
. In some languages, it's part of the syntax of an integer.
– Barmar
Feb 4 at 16:57
7
So it's a bug in their precedence of unary-
.
– Kevin
Feb 4 at 17:47
4
And the winner of counter-intuitive design is ...: Microsoft - once more
– rexkogitans
Feb 5 at 7:30
|
show 8 more comments
According to the precedence table, this is the expected behavior. The operator with higher precedence (/
and *
) is evaluated before operator with lower precedence (unary -
). So this:
-100 / -100 * 10
is evaluated as:
-(100 / -(100 * 10))
Note that this behavior is different from most programming languages where unary negation has higher precedence than multiplication and division e.g. VB, JavaScript.
38
Wow, another gem feature in T-SQL :) I guess I have to audit all of my code now to search for bugs.
– usr
Feb 4 at 14:09
14
oh man. This is even worse than the various PHP ternary operator bugs bugs.php.net/bug.php?id=61915. What sane people think that unary operators must have lower precedence than binary ones?
– phuclv
Feb 4 at 15:22
12
The real difference may be whether-
is considered an operator in-100
. In some languages, it's part of the syntax of an integer.
– Barmar
Feb 4 at 16:57
7
So it's a bug in their precedence of unary-
.
– Kevin
Feb 4 at 17:47
4
And the winner of counter-intuitive design is ...: Microsoft - once more
– rexkogitans
Feb 5 at 7:30
|
show 8 more comments
According to the precedence table, this is the expected behavior. The operator with higher precedence (/
and *
) is evaluated before operator with lower precedence (unary -
). So this:
-100 / -100 * 10
is evaluated as:
-(100 / -(100 * 10))
Note that this behavior is different from most programming languages where unary negation has higher precedence than multiplication and division e.g. VB, JavaScript.
According to the precedence table, this is the expected behavior. The operator with higher precedence (/
and *
) is evaluated before operator with lower precedence (unary -
). So this:
-100 / -100 * 10
is evaluated as:
-(100 / -(100 * 10))
Note that this behavior is different from most programming languages where unary negation has higher precedence than multiplication and division e.g. VB, JavaScript.
edited Feb 5 at 12:55
answered Feb 4 at 11:02
Salman ASalman A
184k67343441
184k67343441
38
Wow, another gem feature in T-SQL :) I guess I have to audit all of my code now to search for bugs.
– usr
Feb 4 at 14:09
14
oh man. This is even worse than the various PHP ternary operator bugs bugs.php.net/bug.php?id=61915. What sane people think that unary operators must have lower precedence than binary ones?
– phuclv
Feb 4 at 15:22
12
The real difference may be whether-
is considered an operator in-100
. In some languages, it's part of the syntax of an integer.
– Barmar
Feb 4 at 16:57
7
So it's a bug in their precedence of unary-
.
– Kevin
Feb 4 at 17:47
4
And the winner of counter-intuitive design is ...: Microsoft - once more
– rexkogitans
Feb 5 at 7:30
|
show 8 more comments
38
Wow, another gem feature in T-SQL :) I guess I have to audit all of my code now to search for bugs.
– usr
Feb 4 at 14:09
14
oh man. This is even worse than the various PHP ternary operator bugs bugs.php.net/bug.php?id=61915. What sane people think that unary operators must have lower precedence than binary ones?
– phuclv
Feb 4 at 15:22
12
The real difference may be whether-
is considered an operator in-100
. In some languages, it's part of the syntax of an integer.
– Barmar
Feb 4 at 16:57
7
So it's a bug in their precedence of unary-
.
– Kevin
Feb 4 at 17:47
4
And the winner of counter-intuitive design is ...: Microsoft - once more
– rexkogitans
Feb 5 at 7:30
38
38
Wow, another gem feature in T-SQL :) I guess I have to audit all of my code now to search for bugs.
– usr
Feb 4 at 14:09
Wow, another gem feature in T-SQL :) I guess I have to audit all of my code now to search for bugs.
– usr
Feb 4 at 14:09
14
14
oh man. This is even worse than the various PHP ternary operator bugs bugs.php.net/bug.php?id=61915. What sane people think that unary operators must have lower precedence than binary ones?
– phuclv
Feb 4 at 15:22
oh man. This is even worse than the various PHP ternary operator bugs bugs.php.net/bug.php?id=61915. What sane people think that unary operators must have lower precedence than binary ones?
– phuclv
Feb 4 at 15:22
12
12
The real difference may be whether
-
is considered an operator in -100
. In some languages, it's part of the syntax of an integer.– Barmar
Feb 4 at 16:57
The real difference may be whether
-
is considered an operator in -100
. In some languages, it's part of the syntax of an integer.– Barmar
Feb 4 at 16:57
7
7
So it's a bug in their precedence of unary
-
.– Kevin
Feb 4 at 17:47
So it's a bug in their precedence of unary
-
.– Kevin
Feb 4 at 17:47
4
4
And the winner of counter-intuitive design is ...: Microsoft - once more
– rexkogitans
Feb 5 at 7:30
And the winner of counter-intuitive design is ...: Microsoft - once more
– rexkogitans
Feb 5 at 7:30
|
show 8 more comments
BOL is correct. -
has lower precedence than *
, so
-A * B
is parsed as
-(A * B)
Multiplication being what it is, you don't typically notice this, except when mixing in the two other binary operators with equal precedence: /
and %
(and %
is rarely used in compound expressions like this). So
C / -A * B
Is parsed as
C / -(A * B)
explaining the results. This is counter-intuitive because in most other languages, unary minus has higher precedence than *
and /
, but not in T-SQL, and this is documented correctly.
A nice (?) way to illustrate it:
SELECT -1073741824 * 2
produces an arithmetic overflow, because -(1073741824 * 2)
produces 2147483648
as an intermediate, which does not fit in an INT
, but
SELECT (-1073741824) * 2
produces the expected result -2147483648
, which does.
"minus" is binary. Unary-
is "negative". People who say things like "minus 10" when they mean "negative 10" are being imprecise.
– Acccumulation
Feb 4 at 18:19
10
@Acccumulation: the imprecision isn't mine. The-
operator, when applied to a single operand, is calledMINUS
in SQL query plans. Its binary counterpart is calledSUB
. If you like, interpret "unary minus" as shorthand for "the unary operator signified by the minus sign" -- a syntactic rather than a semantic designation.
– Jeroen Mostert
Feb 4 at 18:33
3
"negative 10" is standard American usage (I believe) but it is not standard in the UK.
– Alchymist
Feb 5 at 11:11
add a comment |
BOL is correct. -
has lower precedence than *
, so
-A * B
is parsed as
-(A * B)
Multiplication being what it is, you don't typically notice this, except when mixing in the two other binary operators with equal precedence: /
and %
(and %
is rarely used in compound expressions like this). So
C / -A * B
Is parsed as
C / -(A * B)
explaining the results. This is counter-intuitive because in most other languages, unary minus has higher precedence than *
and /
, but not in T-SQL, and this is documented correctly.
A nice (?) way to illustrate it:
SELECT -1073741824 * 2
produces an arithmetic overflow, because -(1073741824 * 2)
produces 2147483648
as an intermediate, which does not fit in an INT
, but
SELECT (-1073741824) * 2
produces the expected result -2147483648
, which does.
"minus" is binary. Unary-
is "negative". People who say things like "minus 10" when they mean "negative 10" are being imprecise.
– Acccumulation
Feb 4 at 18:19
10
@Acccumulation: the imprecision isn't mine. The-
operator, when applied to a single operand, is calledMINUS
in SQL query plans. Its binary counterpart is calledSUB
. If you like, interpret "unary minus" as shorthand for "the unary operator signified by the minus sign" -- a syntactic rather than a semantic designation.
– Jeroen Mostert
Feb 4 at 18:33
3
"negative 10" is standard American usage (I believe) but it is not standard in the UK.
– Alchymist
Feb 5 at 11:11
add a comment |
BOL is correct. -
has lower precedence than *
, so
-A * B
is parsed as
-(A * B)
Multiplication being what it is, you don't typically notice this, except when mixing in the two other binary operators with equal precedence: /
and %
(and %
is rarely used in compound expressions like this). So
C / -A * B
Is parsed as
C / -(A * B)
explaining the results. This is counter-intuitive because in most other languages, unary minus has higher precedence than *
and /
, but not in T-SQL, and this is documented correctly.
A nice (?) way to illustrate it:
SELECT -1073741824 * 2
produces an arithmetic overflow, because -(1073741824 * 2)
produces 2147483648
as an intermediate, which does not fit in an INT
, but
SELECT (-1073741824) * 2
produces the expected result -2147483648
, which does.
BOL is correct. -
has lower precedence than *
, so
-A * B
is parsed as
-(A * B)
Multiplication being what it is, you don't typically notice this, except when mixing in the two other binary operators with equal precedence: /
and %
(and %
is rarely used in compound expressions like this). So
C / -A * B
Is parsed as
C / -(A * B)
explaining the results. This is counter-intuitive because in most other languages, unary minus has higher precedence than *
and /
, but not in T-SQL, and this is documented correctly.
A nice (?) way to illustrate it:
SELECT -1073741824 * 2
produces an arithmetic overflow, because -(1073741824 * 2)
produces 2147483648
as an intermediate, which does not fit in an INT
, but
SELECT (-1073741824) * 2
produces the expected result -2147483648
, which does.
edited Feb 4 at 11:47
answered Feb 4 at 11:11
Jeroen MostertJeroen Mostert
18.2k2456
18.2k2456
"minus" is binary. Unary-
is "negative". People who say things like "minus 10" when they mean "negative 10" are being imprecise.
– Acccumulation
Feb 4 at 18:19
10
@Acccumulation: the imprecision isn't mine. The-
operator, when applied to a single operand, is calledMINUS
in SQL query plans. Its binary counterpart is calledSUB
. If you like, interpret "unary minus" as shorthand for "the unary operator signified by the minus sign" -- a syntactic rather than a semantic designation.
– Jeroen Mostert
Feb 4 at 18:33
3
"negative 10" is standard American usage (I believe) but it is not standard in the UK.
– Alchymist
Feb 5 at 11:11
add a comment |
"minus" is binary. Unary-
is "negative". People who say things like "minus 10" when they mean "negative 10" are being imprecise.
– Acccumulation
Feb 4 at 18:19
10
@Acccumulation: the imprecision isn't mine. The-
operator, when applied to a single operand, is calledMINUS
in SQL query plans. Its binary counterpart is calledSUB
. If you like, interpret "unary minus" as shorthand for "the unary operator signified by the minus sign" -- a syntactic rather than a semantic designation.
– Jeroen Mostert
Feb 4 at 18:33
3
"negative 10" is standard American usage (I believe) but it is not standard in the UK.
– Alchymist
Feb 5 at 11:11
"minus" is binary. Unary
-
is "negative". People who say things like "minus 10" when they mean "negative 10" are being imprecise.– Acccumulation
Feb 4 at 18:19
"minus" is binary. Unary
-
is "negative". People who say things like "minus 10" when they mean "negative 10" are being imprecise.– Acccumulation
Feb 4 at 18:19
10
10
@Acccumulation: the imprecision isn't mine. The
-
operator, when applied to a single operand, is called MINUS
in SQL query plans. Its binary counterpart is called SUB
. If you like, interpret "unary minus" as shorthand for "the unary operator signified by the minus sign" -- a syntactic rather than a semantic designation.– Jeroen Mostert
Feb 4 at 18:33
@Acccumulation: the imprecision isn't mine. The
-
operator, when applied to a single operand, is called MINUS
in SQL query plans. Its binary counterpart is called SUB
. If you like, interpret "unary minus" as shorthand for "the unary operator signified by the minus sign" -- a syntactic rather than a semantic designation.– Jeroen Mostert
Feb 4 at 18:33
3
3
"negative 10" is standard American usage (I believe) but it is not standard in the UK.
– Alchymist
Feb 5 at 11:11
"negative 10" is standard American usage (I believe) but it is not standard in the UK.
– Alchymist
Feb 5 at 11:11
add a comment |
Notice in the documentation that (perhaps counter-intuitively) the order of precedence for - (Negative)
is third.
So you effectively get:
-(100/-(100*10)) = 0
If you place them into variables you won't see this happening, as there is no unary operation that occurs after the multiplication.
So here A and B are the same, whereas C, D, E show the result you are seeing (with E having the complete bracketing)
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
add a comment |
Notice in the documentation that (perhaps counter-intuitively) the order of precedence for - (Negative)
is third.
So you effectively get:
-(100/-(100*10)) = 0
If you place them into variables you won't see this happening, as there is no unary operation that occurs after the multiplication.
So here A and B are the same, whereas C, D, E show the result you are seeing (with E having the complete bracketing)
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
add a comment |
Notice in the documentation that (perhaps counter-intuitively) the order of precedence for - (Negative)
is third.
So you effectively get:
-(100/-(100*10)) = 0
If you place them into variables you won't see this happening, as there is no unary operation that occurs after the multiplication.
So here A and B are the same, whereas C, D, E show the result you are seeing (with E having the complete bracketing)
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
Notice in the documentation that (perhaps counter-intuitively) the order of precedence for - (Negative)
is third.
So you effectively get:
-(100/-(100*10)) = 0
If you place them into variables you won't see this happening, as there is no unary operation that occurs after the multiplication.
So here A and B are the same, whereas C, D, E show the result you are seeing (with E having the complete bracketing)
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
edited Feb 4 at 14:41
Toby Speight
17.1k134367
17.1k134367
answered Feb 4 at 11:24
Jamie PollardJamie Pollard
1,2471819
1,2471819
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54513450%2fa-strange-operation-problem-in-sql-server-100-10010-0%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
7
What's your question?
– Sami
Feb 4 at 9:45
14
Why do you think you have to do with bits, you are working with integers. And integer/integer = integer. So -100/-1000 is 0
– sepupic
Feb 4 at 9:46
5
OK, I do agree, that
-
does seem to be causing the flow to go "wrong". If you try-100/(-100)*10
you get the result10
. it seems that the/
is being applied against to value-
in the equation and then the equation100*10
is being determined. I'm not sure this is an error with BOL, but more that SQL Server isn't behaving as expected. It might be worth raising an issue on sql-docs and seeing what their response is there; perhaps a note could be added to the documentation advising of the "feature".– Larnu
Feb 4 at 10:24
3
SELECT -100/(-100)*10
also returns 10. It looks like-
is treated as the-
operator which should be applied only after100*10
is calculated– Panagiotis Kanavos
Feb 4 at 10:25
7
A / -B * C
isA <div> <negate> B <multiply> C
. Negate has lower precedence than multiply, per the docs, so the result isA / -(B * C)
. You can see this more clearly by using floating constants:12e / -13e * 14e
vs.12e / (-13e) * 14e
vs12e / 13e * 14e
.The reason this throws us off is because we generally expect unary minus to become part of the literal, or at least have very high precedence, but that's not how T-SQL works.– Jeroen Mostert
Feb 4 at 10:36