SRL Archive - General

Pascal WTF


Shatterhand

2014-07-09 16:34:08

I was making some reflection functions in java and used the SRL API as a base. Then I ran into this problem. :)

Ill show the code and outputs in java and pascal.

System.out.println(-648456136 * -1715187017 / 2048.0 * 360); 
OUTPUT 1.40625
Writeln(-648456136 * -1715187017 / 2048.0 * 360);
OUTPUT 1.95508045118177E17

Not the same? Lets see why…

System.out.println(-648456136 * -1715187017);
OUTPUT 8
Writeln(-648456136 * -1715187017);
OUTPUT 8

System.out.println(-648456136 * -1715187017 / 2048.0);
OUTPUT 0.00390625 = 8 / 2048
Writeln(-648456136 * -1715187017 / 2048.0);
OUTPUT 543077903106048 = -648456136 * (-1715187017 / 2048.0)

As you can see, in pascal, when it would overflow, it changes the order. Took some hours to find this. So confusing… :D

Olly

2014-07-09 17:30:17

Wouldn't have happened in Lape. :D

Brandon

2014-07-09 18:09:56

This behaviour is actually undefined in Pascal..

Also pascal as a language is stated to have Left to Right Associativity (order of evaluation) for the following operators:

Highest (precedence)

not
* / div mod and
+ - or
= <> < <= > >=

Lowest (precedence)

.
.
.
BUT..


Within the rules of precedence, order of evaluation of expressions is implementation-defined.
The standard permits operands of an expression to be evaluated differently from the left to right order in which they are written.

For f(x) + g(x), g(x) may be evaluated before f(x) dependent on the values of (x). f(x) may be evaluated before g(x) dependent on the values of (x). - Basically, either one may be evaluated first..

Short circuit boolean evaluation is the only guarantee such that the left is evaluated before the right IFF (if and only if) the value of the expression can be determined solely by the value of the left side.


In other words, the behaviour is actually defined BUT not guaranteed and as such, parenthesis is the only way to guarantee the order of evaluation. That being said, I've never seen something so stupid such that it switches evaluation order when it feels like it and that order isn't guaranteed but only defined. I don't get what the point of having associativity is, if it is implementation defined.


Not sure if Lape actually got it right or wrong.. seeing as it's based on Pascal.. The above logic should also apply. Lol..

Tickyy

2014-07-10 03:00:43

http://www.wolframalpha.com/input/?i=-648456136+*+-1715187017+%2F+2048.0+*+360&dataset=

Our master has spoken!

Shatterhand

2014-07-10 12:35:57

From: Tickyy
http://www.wolframalpha.com/input/?i=-648456136+*+-1715187017+%2F+2048.0+*+360&dataset=

Our master has spoken!

So weird. O.o

Brandon

2014-07-10 12:55:09

From: Shatterhand
So weird. O.o


Wolframalpha is both wrong & right at the same time.


-648456136 * -1715187017 / 2048.0 * 360 = (-648456136 * -1715187017) / 2048.0 * 360 = 1.40625

That will do integer arithmetic and the overflow will occur.. then it'll do the division and you'll get the 1.40625 in PascalScript.

No matter what you do, Wolframalpha and Google will not do this and the overflow will never occur and so the answer will never be what you expected.


Applying this logic (20 digits of precision):

Integer arithmetic first:

printf("%.20f", -648456136 * -1715187017 / 2048.0 * 360); //outputs: 1.40625000000000000000


Floating Point arithmetic first:

printf("%.20f", -648456136 * (-1715187017 / 2048.0 * 360)); //outputs: 195508045118177280.00000000000000000000

And the difference is right to left vs. left to right associativity/order of evaluation.


Another one that confuses a lot of developers is:

-32..

Is it: -(32) or (-3)2 ;)

And for that reason, functions like "pow" take away the confusion.


http://en.wikipedia.org/wiki/Order_of_operations#Exceptions_to_the_standard