challenging operator precedence
|
|
Void Singer
Int vSelf = Sing(void);
Join date: 24 Sep 2005
Posts: 6,973
|
06-02-2009 06:14
we all learned it back in school, Parenthesis, Exponents, (Multiplication, Division), (Addition, Subtraction)....
and you can easily test that addition and subtraction need to be equal with 2-3+4-5 all addition first: -10 all subtraction first: -2 (correctly) in order: -2
whoops subtraction first gives the right answer...
ok lets try this with multiplication and division 3*4/5*6 all * first: 0.4 all / first: 14.4 in order: 14.4
uhm, wait... that order stuff is supposed to be important right?
ok, maybe it's my tired brain, but can anyone show me a case where doing all subtraction before all addition, or all division before all multiplication will change the expected result? I want to say that the associativity of division should mean there is no test case possible, but it seems like there should be one for subtraction. anyone? come on, this is grade school stuff =)
_____________________
| | . "Cat-Like Typing Detected" | . This post may contain errors in logic, spelling, and | . grammar known to the SL populace to cause confusion | | - Please Use PHP tags when posting scripts/code, Thanks. | - Can't See PHP or URL Tags Correctly? Check Out This Link... | - 
|
|
Ron Khondji
Entirely unlike.
Join date: 6 Jan 2007
Posts: 224
|
06-02-2009 09:07
I remember to have learned, but it's long ago  , that addition comes before substraction and multiplication before division, so the correct answers would be -10 and 0.4. Edit: Well I just Googled my memory and it looks to be completely out of date. Please disregard my above comment  .
|
|
Meade Paravane
Hedgehog
Join date: 21 Nov 2006
Posts: 4,845
|
06-02-2009 09:17
From: Ron Khondji I remember to have learned, but it's long ago  , that addition comes before substraction and multiplication before division, so the correct answers would be -10 and 0.4. Close but exactly backwards: * and / are evaluated before + and -. If there are more than one of these in a given statement, they're evaluated left-to-right. random google link: it's probably close to this http://www.cppreference.com/wiki/operator_precedence - just ignore operators that don't apply in LSL.
_____________________
Tired of shouting clubs and lucky chairs? Vote for llParcelSay!!! - Go here: http://jira.secondlife.com/browse/SVC-1224- If you see "if you were logged in.." on the left, click it and log in - Click the "Vote for it" link on the left
|
|
Thex Lecker
Registered User
Join date: 30 Nov 2008
Posts: 2
|
06-02-2009 10:40
From: Void Singer 2-3+4-5
3*4/5*6
Not sure of your point exactly, it may further your understanding if you re-write these expressions as a computer typically sees them: 2 + -3 + 4 + -5 3 * 4 * 5^-1 * 6 (order of operations exponents first) 3 * 4 * 0.2 * 6
|
|
Dora Gustafson
Registered User
Join date: 13 Mar 2007
Posts: 779
|
06-02-2009 11:09
From: Void Singer we all learned it back in school, Parenthesis, Exponents, (Multiplication, Division), (Addition, Subtraction)....
and you can easily test that addition and subtraction need to be equal with 2-3+4-5 all addition first: -10 all subtraction first: -2 (correctly) in order: -2
whoops subtraction first gives the right answer...
ok lets try this with multiplication and division 3*4/5*6 all * first: 0.4 all / first: 14.4 in order: 14.4
uhm, wait... that order stuff is supposed to be important right?
ok, maybe it's my tired brain, but can anyone show me a case where doing all subtraction before all addition, or all division before all multiplication will change the expected result? I want to say that the associativity of division should mean there is no test case possible, but it seems like there should be one for subtraction. anyone? come on, this is grade school stuff =) This make no sense. What are you trying to say? Precedences vary from one programming language to another. They are exactly the way you or the programming language at hand define them. APL for instance: There are no precedence rules in APL: statements are simply read from right to left. For example, 12 - 3 + 4 yields 5, same as 12 - (3 + 4)
_____________________
From Studio Dora
|
|
Argent Stonecutter
Emergency Mustelid
Join date: 20 Sep 2005
Posts: 20,263
|
06-02-2009 11:12
Subtraction is not associative.
1 - 3 - 2 is (1 - 3) - 2, not 1 - (3 - 2).
Division is not associative.
1 / 3 / 3 is (1 / 3) / 3, not 1 / (3 / 3).
Subtraction is "left associative", but this doesn't mean it's "associative", it's just a notational convenience to avoid having to fully parenthesize expressions. Left-associative is not a special kind of associativity, it's a special kind of non-associativity.
|
|
Void Singer
Int vSelf = Sing(void);
Join date: 24 Sep 2005
Posts: 6,973
|
06-02-2009 17:07
From: Argent Stonecutter Subtraction is not associative.
1 - 3 - 2 is (1 - 3) - 2, not 1 - (3 - 2).
Division is not associative.
1 / 3 / 3 is (1 / 3) / 3, not 1 / (3 / 3).
Subtraction is "left associative", but this doesn't mean it's "associative", it's just a notational convenience to avoid having to fully parenthesize expressions. Left-associative is not a special kind of associativity, it's a special kind of non-associativity. fair enough for the wording.... and since Dora asked all subtraction before addition: (2 - 3) + (4 - 5) = -2 vs Normal order of Operations: ((2 - 3) + 4) - 5 = -2 and all division before multiplication: 2 * (3 / 4) * 5 = 7.5 vs Normal order of Operations: ((2 * 3) / 4) * 5 = 7.5 I'm wondering if there are any cases where promoting - to a higher precedence than + (instead of equal precedence) or doing the same for / and *, will change the result. I can't see a case where it does... to break it down to simplistic calculator function or 2 operators (+-) while (~subtractionIsFound){ operator = "+"; right_side = -right_side; } //-- then while (~additionIsFound){ result = left_side + right_side; } which processes subtraction twice (once to convert, once to add, to preserve order) vs while (~subtractionIsFound){ result = left_side - right_side; } //-- then while (~additionIsFound){ result = left_side + right_side; } which processes each operation only once we're taught that the second version breaks the order of operations, and loses communicability(at least that's what I believe we're discussing... the terms are a jumble right now), and if you process addition first, that is the case... but I can't see a case where processing subtraction first breaks communicability. nor the same scenario with division before multiplication.
_____________________
| | . "Cat-Like Typing Detected" | . This post may contain errors in logic, spelling, and | . grammar known to the SL populace to cause confusion | | - Please Use PHP tags when posting scripts/code, Thanks. | - Can't See PHP or URL Tags Correctly? Check Out This Link... | - 
|
|
Argent Stonecutter
Emergency Mustelid
Join date: 20 Sep 2005
Posts: 20,263
|
06-02-2009 18:43
You're thinking of commutativity. Commutativity is stronger than associativity.
3 + 4 = 4 + 3 // addition is commutative
2 + (3 + 4) = (2 + 3) + 4 // addition is associative
Subtraction can be converted to addition, and then it becomes commutative and associative:
1 - 3 = 1 + (-3) = (-3) + 1
This means that if you fully parenthesize subtraction you don't change the result:
1 + 2 - 3 = 1 + (2 - 3) = 1 + (2 + (-3)) = (2 + (-3)) + 1 = (2 - 3) + 1
Which is the result you noticed: parentheses define the order of evaluation, so you can evaluate subtraction first, within the convention of left-associativity.
Edit: you can't be quite as blithe with multiplication and division because of division by zero.
Also, when you're dealing with floating point numbers addition is not necessarily associative. Consider adding three floating point numbers near zero: you can get an underflow in some orders of evaluation but not others.
|
|
Darien Caldwell
Registered User
Join date: 12 Oct 2006
Posts: 3,127
|
06-02-2009 19:33
The Rule was MDAS (multiplication/Division/Addition/Subtraction).
It was to standardise the way expressions were evauated. Because you can get different answers depending on whether you do the addition/subtraction first, or the Multiplication/division first. There was no rule that addition should come before or after subtraction, it was that multiplication/division should come before addition/subtraction.
4 * 4 + 4 can give two answers, depending on if you do the Addition first, or the multiplication first:
(4 * 4) + 4 = 20 4 * (4 + 4) = 32
I believe this must be what you are thinking of.
|
|
Void Singer
Int vSelf = Sing(void);
Join date: 24 Sep 2005
Posts: 6,973
|
06-02-2009 21:40
From: Darien Caldwell The Rule was MDAS (multiplication/Division/Addition/Subtraction).
It was to standardise the way expressions were evauated. Because you can get different answers depending on whether you do the addition/subtraction first, or the Multiplication/division first. There was no rule that addition should come before or after subtraction, it was that multiplication/division should come before addition/subtraction.
4 * 4 + 4 can give two answers, depending on if you do the Addition first, or the multiplication first:
(4 * 4) + 4 = 20 4 * (4 + 4) = 32
I believe this must be what you are thinking of. actually no, you almost illustrate my point... if you precedence addition over subtraction, you'll get a different answer than if you evaluate then as discovered (considering only those two operators for the moment). but you seem to get the SAME answer if you precedence subtraction... so in the example in my last post, both methods presented seem to give the correct result, but only one strictly obey the order of precedence we're all taught in grade school... and the other one halve the number of operation done when when an operation is subtraction, or division... which is definitely an important speed up.... IF it holds true... I'm not finding a case where it doesn't (if anyone wants to know why I'm looking at this I was about to open source my own simple calculator, which uses the convert and apply method, and I decided to check up on whaat other ones were available on the forum... and noticed one uses the other method so I tested the ordering with all the basic proofs I could think of (the one on forum I have in mind is broken in this regard, but if the order were reversed, it looks like it'd work) PS yes I skipped the special case for division, it's handled as an error in mine, I briefly considered methods for ignoring it, like (a / (b + !b)) or (a / (b + !b*a)) or even (a / (b + !b) * (b != 0)), which ignore divide by zero results as 'a', '1', and '0' respectively... i figured the (handled) error was actually the most useful. and my spell checker didn't like commutativity so I added it =)
_____________________
| | . "Cat-Like Typing Detected" | . This post may contain errors in logic, spelling, and | . grammar known to the SL populace to cause confusion | | - Please Use PHP tags when posting scripts/code, Thanks. | - Can't See PHP or URL Tags Correctly? Check Out This Link... | - 
|
|
Argent Stonecutter
Emergency Mustelid
Join date: 20 Sep 2005
Posts: 20,263
|
06-03-2009 04:26
Anyway, if you're doing a recursive descent parser it's easiest to treat subtraction and addition at the same level, and if you're building shift/reduce tables for an operator precedence parser it doesn't matter because everything's just about as easy (or as hard).  [no ferret 'cos scripting tips doesn't show pictures]
|
|
Void Singer
Int vSelf = Sing(void);
Join date: 24 Sep 2005
Posts: 6,973
|
06-03-2009 05:24
From: Argent Stonecutter Anyway, if you're doing a recursive descent parser it's easiest to treat subtraction and addition at the same level, and if you're building shift/reduce tables for an operator precedence parser it doesn't matter because everything's just about as easy (or as hard).  [no ferret 'cos scripting tips doesn't show pictures] aww, I like your ferret pictures, ya shoulda linked it anyway =) it's an nested iterative descent parser, for a "natural language" style with all the implied multiplication and negation you care to write into your equation. it's already built actually, long time back... I just hate to see wasted cycles so I was tweaking it a bit when I cottoned on to this weirdness... and since it'll cost me half the cycles for those two operators while parsing actual operations, it's actually a good thing to know. it may apply latter when I add boolean and bitwise support =)
_____________________
| | . "Cat-Like Typing Detected" | . This post may contain errors in logic, spelling, and | . grammar known to the SL populace to cause confusion | | - Please Use PHP tags when posting scripts/code, Thanks. | - Can't See PHP or URL Tags Correctly? Check Out This Link... | - 
|
|
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
|
06-03-2009 08:07
Yeah. Anyone up for building a yacc type parser generator in LSL? **Shudders** (At one time I might have had the energy and motivation for that kind of project. Now it just...ouch.)
|
|
Void Singer
Int vSelf = Sing(void);
Join date: 24 Sep 2005
Posts: 6,973
|
06-03-2009 14:58
From: Hewee Zetkin Yeah. Anyone up for building a yacc type parser generator in LSL? **Shudders** (At one time I might have had the energy and motivation for that kind of project. Now it just...ouch.) ewwwwww no, standard math calculator, float, brace, and 6 basics operations, with no special limits on equation length or entry types, all exceptions handled to error messages. I need to tweak it to allow native hex and C99 float conversions, and separator markings, but other than that it was done long ago it's actually similar to Zindorff's looking at it (although that one has broken precedence) but with error handling and without support for e or trig functions (I may toss that in there, that one is broken for stacked trig operators, but it's expensive to search from the end of a list in LSL, so it's not a priority to code it.)
_____________________
| | . "Cat-Like Typing Detected" | . This post may contain errors in logic, spelling, and | . grammar known to the SL populace to cause confusion | | - Please Use PHP tags when posting scripts/code, Thanks. | - Can't See PHP or URL Tags Correctly? Check Out This Link... | - 
|