Skip to content

Unary negation has different precedence than in Vensim #569

@chrispcampbell

Description

@chrispcampbell

I'm not sure this is really a bug in SDEverywhere (seems like a bug in Vensim), but I'm filing an issue for tracking purposes.

According to Vensim's documentation on Operators, unary negation should have higher precedence than other operators like ^. However, I came across a case (in the model from #557) where Vensim and SDEverywhere produce different results when mixing unary negation and ^.

Simplified example:

a = 3 ~~|
b = -3^2 ~~|
c = -a^2 ~~|

For b and c, Vensim produces -9, but SDEverywhere produces 9.

In other words, Vensim treats it like -(a^2) while SDEverywhere (specifically the antlr-vensim parsing grammar) treats it like (-a)^2 (technically we translate it to pow(-a, 2)).

The workaround is to add parentheses to make the order of operations explicit, depending on your desired goal:

c = (-a)^2 ~~|
OR
c = -(a^2) ~~|

Given the ambiguity (see note below about how JavaScript handles this case), I'm not sure we should change SDEverywhere to match Vensim's behavior. Perhaps it would be better to flag it as a warning.

As an aside, JavaScript treats a similar example as an error (forcing you to add parentheses); see related SO discussion and this REPL example:
Image

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions