BUG in MOD Function (OpenInsight Specific)
At 10 JUL 2000 03:34:17PM Don Miller - C3 Inc. wrote:
In our app, we do a lot of date arithmetic including day of week calculations. In AREV we would calculate day of week as follows:
DOW=MOD(Desired_Date,7)+1which returns a day number from 1 to 7 with day 1 being Sunday. In OI if you do this on a date that has a negative sign in internal format, you get a negative number. bummer
The only way around it is to compute MOD yourself:
DOW=Desired_Date - INT((Desired_Date/7)*7)+1Anybody else found this???
Don Miller
C3 Inc.
At 10 JUL 2000 03:54PM Oystein Reigem wrote:
Don,
It sounds familiar. I think I must have come across it. I even thought it was documented somehow.
But it isn't. Actually the docs say:
The modulo (remainder) is calculated by the following formula: Mod(X,Y)=X - (Int(X/Y) * Y)
Which is a lie.
But it also hints at a workaround: Use the formula
(Int(X/Y) * Y)
instead!
I'm certain somebody else must have seen it, e.g when trying to calculate day of week before day 0 according to Revelation.
- Oystein -
At 10 JUL 2000 06:43PM Paul Rule wrote:
Without actually testing this, how about…
DOW=ABS(MOD(Desired_Date,7))+1
At 11 JUL 2000 04:30AM Oystein Reigem wrote:
Aaarg! Here I am with my degree in Maths and manage to get it wrong! My excuse is I haven't got a degree in Cut & Paste.
Here - with some luck - is the correct version:
The docs say about the Mod function that it is
calculated by the following formula: Mod(X,Y)=X - (Int(X/Y) * Y)
This formula is correct and works for all integers - also when X is negative. So one can use that instead of the Mod function.
OI's Mod fails miserably on negative numbers, so it's a lie that the Mod funcion calculates according to that formula.
To get DOW set Y=7 and add 1:
DOW(X)=X - (Int(X/7) * 7) + 1
(The range of a properly working Mod(X, Y) function is {0, 1, 2, …, Y-1}, while the range of DOW is shifted 1 higher.)
Mike's and Paul's formulas are both wrong. They fail on negative numbers.
Here's a function that compares all four of them - OI's Mod vs the correct formula vs Mike's formula vs Paul's formula. (I've subtracted 1 from Mike's and Paul's formulas since their formulas are for DOW and not Mod):
function Compare_Mod( N, M ) return "OI Mod " : Mod(N, M) : " vs correct formula " : N - (Int(N/M) * M) : " vs Mike " : Abs(Mod(N, M) + 1) - 1 : " vs Paul " : Abs(Mod(N, M))To see the result on -10 function Test_Mod( Dummy )
equate CrLf to Char(13) : Char(10) declare function Compare_Mod List=" for N=-10 to 10 List := N : " mod " : 7 : ": " : Compare_Mod( N, 7 ) : CrLf next Nreturn List
</code>
- Oystein -
At 12 JUL 2000 12:17AM Richard Hunt wrote:
I dont think its a bug. The MOD function is suppose to supply the remainder. And well the remainder is negative for a negative division.
Just to let you know… That is how the MOD function works for many different basic programming applications.
At 12 JUL 2000 06:11AM Oystein Reigem wrote:
Richard,
Did somebody say it's different in Arev and OI? Then it's a bug.
And Mod not working according to the docs means it's either a bug or an error in the docs.
Finally - if the OI Mod function is supposed to be a mathematical modulo function it's a bug. The mathematical modulo function sort of wraps the number line around a circle. E.g the positive end clockwise and the negative end counterclockwise. Like a time line around a watch face. So the time at -13 hours relative zero (midnight or midday) is not -1 (the remainder -1 after dividing by 12 (the circumference)). It's 11.
- Oystein -