Operator MOD
#21
Jack
Only one valid: Print fmod (1.4 #, 5 #) => 1.4 ok.

Chris
Reply
#22
Pete 
All results correct. 
It's not like I only have one separate expression and can use a function procedure. What I have given is just a fragment of a much longer mammatic formula and I cannot use the proposed function just like that. Someone wrote that the new operator is unnecessary because someone wrote the procedure. And why write procedures, if you can type three or four letters of the operator's name. It is also good to undermine the sense of existence: ABS, INT, etc., since it can be replaced by a functional procedure. Life must be made easier. Hence my proposal of a new operator.

Chris
Reply
#23
If one function can't get the job done, one keyword wouldn't get the job done either.

Pete
If eggs are brain food, Biden takes his scrambled.
Reply
#24
"KCalc" supports Chris. But "Galculator" does not, goes along with QB64(PE).

In other words, "KCalc", an accessory for KDE Plasma D.E. (I tested on NeptuneOS) always returns a positive result from negative dividend and positive divisor. With this program from -27 MOD 5 the answer is 3.

However, "Galculator" which I reckon was created by GNOME but running and posting this from EndeavourOS/Falkon, the results are negative. I try with -27 MOD 5 and get -2.

FROM:

https://en.wikipedia.org/wiki/Modulo_operation

Quote:When exactly one of a or n is negative, the naive definition breaks down, and programming languages differ in how these values are defined.

I think is what Chris is trying to say is he would rather write "-1 pmod 5" instead of "pmod(-1, 5)", assuming the "pmod()" is the user's function to make sure modulo is positive. Or even better, write "-1 MOD 5" instead of "-1 PMOD 5". To him, "MOD" is as sacred as plus, minus and whatever else is an operator and therefore it shouldn't be written as function call. Sadly, to be able to do that, QB64(PE) would have to support OOP and the programmer would have to override "MOD" operator, like actually has to be done in C++.
Reply
#25
Out of boredom I took some examples from Wikipedia. They are in the form of subprograms for when it's not tolerated if the result of division is zero, which is possible in some long-winded calculations. Using a subprogram is clumsy but I don't recommend using a "FUNCTION" to try to return more than one value, one which is the LHS of assignment (FUNCTION-NAME = value) and the other which is one of the parameters, because it confuses beginner and intermediate BASIC programmers. Side-effects are good only for those who know what they are doing. Some of you are saying, "oh just assign q and r as part of sub parameter list", but I did it this way to emphasize that the last two values are going to be changed by the subprogram.

Code: (Select All)
''from C functions displayed in:
''https://en.wikipedia.org/wiki/Modulo_operation
''by mnrvovrfc

''CHANGED: quot, remd
''remd = -1 if denom = 0, otherwise remd is expected to be positive
''must use integer division because "regular" division doesn't work properly in QB64
sub ldive(numer as _integer64, denom as _integer64, quot as _integer64, remd as _integer64)
    dim q as _integer64, r as _integer64
    if denom = 0 then
        quot = 0
        remd = -1
        exit sub
    end if
    q = numer \ denom
    r = numer MOD denom
    if r < 0 then
        if denom > 0 then
            q = q - 1
            r = r + denom
        else
            q = q + 1
            r = r - denom
        end if
    end if
    quot = q
    remd = r
end sub

''CHANGED: quot, remd
''remd = -1 if denom = 0
sub ldivf(numer as _integer64, denom as _integer64, quot as _integer64, remd as _integer64)
    dim q as _integer64, r as _integer64
    if denom = 0 then
        quot = 0
        remd = -1
        exit sub
    end if
    q = numer \ denom
    r = numer MOD denom
    if (r > 0 and denom < 0) or (r < 0 and denom > 0) then
        q = q - 1
        r = r + denom
    end if
    quot = q
    remd = r
end sub
Reply
#26
My bet is he's looking for a reliable pattern that follows the counting sequence. In this case there are 0 to 6 representations. Hats off to Steve for picking that out of his first post.

Thinking back, I might have thought MOD would have accomplished a reliable pattern for files, which is true except for a return of zero, which can be adjusted to the modulo. I vaguely remember doing something later where whatever it was I was tracking could go negative. That's when I discovered i had to write a function to compensate for negatives to maintain the pattern, not just the positive sign.

Fun stuff, and I see it spurred Steve into chucking the Magic 8-Ball and making the keyword for the day, MOD.

Pete
Reply
#27
(11-28-2022, 01:17 AM)mnrvovrfc Wrote: ... "MOD" is as sacred as plus, minus and whatever else is an operator and therefore it shouldn't be written as function call. Sadly, to be able to do that, QB64(PE) would have to support OOP and the programmer would have to override "MOD" operator, like actually has to be done in C++.

Look what has to be done in Freebasic only to get a "-9 MOD 5" which returns 1 instead of -4:

Code: (Select All)
Type ANUM
    As Integer n
End Type

operator Mod ( byref number1 as ANUM, byref number2 as ANUM ) as integer
    dim templ as integer
    templ = number1.n MOD number2.n
    IF number1.n < 0 THEN templ = (templ + number2.n) MOD number2.n
    return templ
end operator

dim i as integer, a as ANUM, d as ANUM
d.n = 5
for i = -10 to 10
    a.n = i
    print i; " mod"; 5, a mod d
next

An UDT is terminally needed so the programmer could still use the ordinary "MOD".
Reply
#28
@Chris
Mathematica gives the following answers
Mod[-1, 5] -> 4
Mod[-1.4, 5] -> 3.6
Mod[1.4, 5] -> 1.4
Mod[-7, 5] -> 3
Mod[-7.1, 5] -> 2.9

while Mathematica is ok with floating point numbers Maple's mod operator only deals with integers, for -1 mod 5 it gives 4

-- edit --
Mod[-1, -5] -> -1
Mod[-1.4, -5] -> -1.4
Mod[1.4, -5] -> -3.6
Mod[-7, -5] -> -2
Mod[-7.1,- 5] -> -2.1

-- edit2 --
Mod[-1, 5.2] -> 4.2
Mod[-1.4, 5.2] -> 3.8
Mod[1.4, 5.2] -> 1.4
Mod[-7, 5.2] -> 3.4
Mod[-7.1, 5.2] -> 3.3

Mod[-1, -5.2] -> -1
Mod[-1.4, -5.2] -> -1.4
Mod[1.4, -5.2] -> -3.8
Mod[-7, -5.2] -> -1.8
Mod[-7.1,- 5.2] -> -1.9
Reply
#29
@Chris
let me know if this seems correct to you

Code: (Select All)
Print fmod(-1, 5), " -> 4"
Print fmod(-1.4, 5), " -> 3.6"
Print fmod(1.4, 5), " -> 1.4"
Print fmod(-7, 5), " -> 3"
Print fmod(-7.1, 5), " -> 2.9"

Print fmod(-1, -5), " -> -1"
Print fmod(-1.4, -5), " -> -1.4"
Print fmod(1.4, -5), " -> -3.6"
Print fmod(-7, -5), " -> -2"
Print fmod(-7.1, -5), " -> -2.1"

Print fmod(-1, 5.2), " -> 4.2"
Print fmod(-1.4, 5.2), " -> 3.8"
Print fmod(1.4, 5.2), " -> 1.4"
Print fmod(-7, 5.2), " -> 3.4"
Print fmod(-7.1, 5.2), " -> 3.3"

Print fmod(-1, -5.2), " -> -1"
Print fmod(-1.4, -5.2), " -> -1.4"
Print fmod(1.4, -5.2), " -> -3.8"
Print fmod(-7, -5.2), " -> -1.8"
Print fmod(-7.1, -5.2), " -> -1.9"

Function fmod# (x As Double, y As Double)
    fmod = x - Int(x / y) * y
End Function
Reply
#30
Jack

All results correct.

Regards - Chris
Reply




Users browsing this thread: 3 Guest(s)