|
Arde Enchanter
Joined: 09 Sep 2007 Posts: 605
|
Posted: Fri Oct 12, 2007 2:31 pm
[2.05] Weird math result |
I've found some strange results while debugging a long script which calculates various character' experience-related info. At first I thought that there is something wrong with my #FUNCs or I just miss a parenthesis. But when I narrowed this problem down to bare numbers, I've understand that it was not the script.
Here is the example with numbers from my script, don't wonder about values and their meaning:
Code: |
#SAY %eval(100*(110000000 - 1644069)/110000000) |
This code will show -18 as the answer, instead of 98.
Some more examples:
%eval(100*11000000/11000000) =1 (ok)
%eval(100*60000000/60000000) = 28 (wrong)
%eval((100*60000000)/60000000) = 28 (wrong)
%eval(100*600000000/600000000) = 0 (wrong)
%eval(10*60000000/60000000) = 10 (ok)
%eval(60000000/60000000) =1 (ok)
%eval(5*1200000000/1200000000) = 1 (wrong)
%eval(1200000000/1200000000) = 1 (ok)
%eval(1200000000000/1200000000000) = 1 (ok)
Looks like an overflow in some cases (after first multiplication operator, division itself works normal even on large numbers), but CMUD is supposed to use 64-bit integers? |
|
|
|
Fang Xianfu GURU
Joined: 26 Jan 2004 Posts: 5155 Location: United Kingdom
|
Posted: Fri Oct 12, 2007 2:47 pm |
It's weird that the priority of the different operators seems to vary. For example:
%eval(100*600000000/600000000) = 0 (wrong)
%eval(10*60000000/60000000) = 10 (ok)
The first one's actually the way it should be because division takes priority over multiplication. But that's changed in the second one, when the multiplication is taking priority over the division, which is wrong. |
|
|
|
Arde Enchanter
Joined: 09 Sep 2007 Posts: 605
|
Posted: Fri Oct 12, 2007 3:00 pm |
Fang Xianfu wrote: |
The first one's actually the way it should be because division takes priority over multiplication. But that's changed in the second one, when the multiplication is taking priority over the division, which is wrong. |
Here (http://forums.zuggsoft.com/modules/mx_kb/kb.php?mode=doc&page=3&refpage=3&a=cmud_Expression) stated that multiplication has higher priority then division. Sometimes CMUD acts this way:
%eval(100*60000000/60000000) = 28 (wrong)
%eval((100*60000000)/60000000) = 28 (wrong)
You can see no effect from extra parenthesizes.
But it would be better if these operators have equal priorities and evaluates from left to right. |
|
|
|
Zugg MASTER
Joined: 25 Sep 2000 Posts: 23379 Location: Colorado, USA
|
Posted: Fri Oct 12, 2007 5:57 pm |
Actually, in the Yacc parser file that defines the CMUD script syntax, Multiply and Divide (and Modulus) all have the same priority. This is true in many languages, and you should always use parenthesis to ensure that your expressions are executed as expected. Otherwise the result is undefined. In theory, the multiplication should execute before the division because of the order of the statements in the Yacc parser file, but I don't fully understand all of the hidden workings of Yacc, and since technically the numeric priorities are the same, there might be cases where the parser performs in the wrong order.
When playing around with your example, I don't think the problem is with the priority order. If you look at the compiled code, it *is* doing the multiply first in both cases. But in the first case you are generating a result that is overflowing some internal integer value somewhere. CMUD is mostly 32bit code and only uses 64bit integers in certain places, so maybe there is a problem with that. |
|
|
|
|
|