math : absolute modulo

Share your advanced PureBasic knowledge/code with the community.
Olli
Addict
Addict
Posts: 1071
Joined: Wed May 27, 2020 12:26 pm

math : absolute modulo

Post by Olli »

Debug modu(-1, 4) will give 3 (but not -1)
Debug modu(x, 0) will give 0
Debug modu(x, -y) will give 0... nop : will give same as modu(x, y)

Code: Select all

Procedure modu(x, n)
   Protected r   ; (thanks to STARGÅTE)
   If n > 0
      r = x % n
      If x < 0 And r
         If n > 0
            r + n
         Else
            r - n
         EndIf
      EndIf
   EndIf
   ProcedureReturn r
EndProcedure

Procedure aDiv(a, b)
   Protected r = a / b
   If a < 0
      If r < 0
         r - 1
      Else
         r + 1
      EndIf
   EndIf
   ProcedureReturn r
EndProcedure
Last edited by Olli on Sun Oct 02, 2022 5:33 pm, edited 8 times in total.
User avatar
STARGÅTE
Addict
Addict
Posts: 2067
Joined: Thu Jan 10, 2008 1:30 pm
Location: Germany, Glienicke
Contact:

Re: math : absolute modulo

Post by STARGÅTE »

Please use Protected inside a procedure to define a variable, not Define.
Define inside a procedure would raise an error, when r would be defined a globale by the user.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Lizard - Script language for symbolic calculations and moreTypeface - Sprite-based font include/module
Olli
Addict
Addict
Posts: 1071
Joined: Wed May 27, 2020 12:26 pm

Re: math : absolute modulo

Post by Olli »

I apologize : "Protected" contains 9 characters. It is too hard...
Olli
Addict
Addict
Posts: 1071
Joined: Wed May 27, 2020 12:26 pm

Re: math : absolute modulo

Post by Olli »

I have any "Define" everywhere in my procedures. You have killed me, STARGÅTE :lol: Everywhere...
I use however "Global" directive, but it is temporary... After a time, everything is closed in procedures without global variables...
User avatar
mk-soft
Always Here
Always Here
Posts: 5333
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: math : absolute modulo

Post by mk-soft »

With Define, variables are declared in the main programme (main scope). With Shared, these are passed on in procedures.
With Protected, variables are declared in procedures. With Static, these variables are also available in the procedure the next time it is called.
With Global, the variables are accessible everywhere. Therefore use as little as possible (name conflicts).
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
Olli
Addict
Addict
Posts: 1071
Joined: Wed May 27, 2020 12:26 pm

Re: math : absolute modulo

Post by Olli »

Yes.

I also added a condition in the way of negative diviser. Now, all is really treated as if the signs did not exist.

But, I doubt about the behaviour in the way the diviser is negative. I.e. :

modu(i, 3) gives 0, 1, 2, 0, 1, 2, 0, 1, 2, etc... with i from -3 to 5.

Does modu(i, -3) give this ? : 2, 1, 0, 2, 1, 0, 2, 1, 0, etc...
with modu(0, -3) = 2 ?

--> I think I will copy a part of this, to the Coding questions section, because I also find that modu(m, -n) = 0
User avatar
STARGÅTE
Addict
Addict
Posts: 2067
Joined: Thu Jan 10, 2008 1:30 pm
Location: Germany, Glienicke
Contact:

Re: math : absolute modulo

Post by STARGÅTE »

Olli wrote: Sun Oct 02, 2022 12:04 pm Does modu(i, -3) give this ? : 2, 1, 0, 2, 1, 0, 2, 1, 0, etc...
with modu(0, -3) = 2 ?
It depends, how you want to define it.
In Pure Basic the sign of the remainder is the sign of the dividend.
In math or other languages it is also common to define the sign of the remainder by the sign of the divisor.

Here are some examples:

Code: Select all

 7 %  3 = 1
-7 %  3 = 2
 7 % -3 = -2
-7 % -3 = -1
BTW: At the moment you code has a system error, because of the last EndIf, instead of EndProcedure.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Lizard - Script language for symbolic calculations and moreTypeface - Sprite-based font include/module
Olli
Addict
Addict
Posts: 1071
Joined: Wed May 27, 2020 12:26 pm

Re: math : absolute modulo

Post by Olli »

wrote:BTW: At the moment you code has a system error, because of the last EndIf, instead of EndProcedure.
oo... I quickly changed it to the right keyword... Do not worry, it was a sunday illusion...
wrote:Here are some examples[...]
I am not a lot agree with this.

mul and div signs rule is a xor op :

Code: Select all

0 ! 0 = 0
0 ! 1 = 1
1 ! 0 = 1
1 ! 1 = 0

so 

-x * -x = y
-x * +x = -y
+x * -x = -y
+x * +x = y
Since I started to code I needed sometimes the equivalent of

Code: Select all

x & mask
for other numbers that binaries ones. And it also happens that sometimes I need a perfect periodic modulo which is not fully transformed by the sign. Which domain ? I don't remember actually, but sure, it will be a time when I could give an example.
User avatar
STARGÅTE
Addict
Addict
Posts: 2067
Joined: Thu Jan 10, 2008 1:30 pm
Location: Germany, Glienicke
Contact:

Re: math : absolute modulo

Post by STARGÅTE »

Olli wrote: Sun Oct 02, 2022 1:39 pm I am not a lot agree with this.

mul and div signs rule is a xor op :
You give here the rules for the the quotient, not the remainder!

Code: Select all

 7 /  3 = 2 R 1 , because 2*3+1 = 7
-7 /  3 = -3 R 2 , because -3*3+2 = -7
 7 / -3 = -3 R -2 , because -3*-3-2 = 7
-7 / -3 = 2 R -1 , because 2*-3-1 = -7
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Lizard - Script language for symbolic calculations and moreTypeface - Sprite-based font include/module
Olli
Addict
Addict
Posts: 1071
Joined: Wed May 27, 2020 12:26 pm

Re: math : absolute modulo

Post by Olli »

Okay...

I modified modu(a, b) to keep negative divisors and treat with them.
And I added aDiv(a, b) to allow all the tests. Normally, we must not be too bad :lol:

I have to stop to give such headaches to myself...

Here is a truth table to compare some light details.

Code: Select all

-7 // -3 =  3 R 2
-7 //  3 = -3 R 2
 7 // -3 = -2 R 1
 7 //  3 =  2 R 1
Post Reply