The MOD() Function

Share your advanced PureBasic knowledge/code with the community.
oldefoxx
Enthusiast
Enthusiast
Posts: 532
Joined: Fri Jul 25, 2003 11:24 pm

The MOD() Function

Post by oldefoxx »

Mod() for Modulus, returns the remainder of an integer divide operation, and is only intended for use with unsigned integers. It is much more effecitve to have the Mod() function written in ASM rather than in PB,
since multiple steps are required in PB to achieve the same end.

In ASM. using the registers, the register pair DX,AX can be used to hold a double-word, and this can be divided by any word (16 bit) reference, with the AX register receiving the Integer result, and the DX register receiving the remainder (the potion we want to have returned).

A variation of the register approach has the word to be divided into in the AX register, and this can be divided by a byte (8 bit) value, and the integer result will be in AL, with the remainder in AH.

For greatest flexability, we would normally elect to use the first form.

Code: Select all

Procedure.w Mod(value1.w,base1.w)
 temp1.w
     MOV ax,value1
     XOR dx,dx
     DIV base1
     MOV temp1,dx
     ProcedureReturn temp1
EndProcedure

OpenConsole()
ConsoleColor(15,1)
For a.w=1 To 50
  Print("Mod("+Str(a)+",13) ==> "+Str(Mod(a,13)))
  If (a & 1) 
    ConsoleLocate(39,a/2)
  ElseIf a<50
    PrintN("")
  EndIf
Next
While Inkey()=""
Wend
has-been wanna-be (You may not agree with what I say, but it will make you think).
freak
PureBasic Team
PureBasic Team
Posts: 5940
Joined: Fri Apr 25, 2003 5:21 pm
Location: Germany

Post by freak »

Why don't you use the PB mod ( % ) operator?

Code: Select all

a = 7
b = 4
Debug a % b
Timo
quidquid Latine dictum sit altum videtur
dontmailme
Enthusiast
Enthusiast
Posts: 537
Joined: Wed Oct 29, 2003 10:35 am

Post by dontmailme »

:lol:

Well, with the help file it's sometimes hard to find what you want ;)

:lol:
Paid up PB User !
oldefoxx
Enthusiast
Enthusiast
Posts: 532
Joined: Fri Jul 25, 2003 11:24 pm

Another example

Post by oldefoxx »

Frankly, I was not aware of it. The Help file is not much help on special
character operators, and I could not find a Mod() or Modulo() function
listed. Since others have made inquiries as well, I just figured that it was a neglected topic.

Anyway, I've since learned a couple of other facts about interfacing PB and ASM, which has lead to a slightly enhanced version of Mod(). This one
allows long values, but it does not perform signed arithmetic. There is an example on the forum for handling signed arithmetic if that is what you are looking for.

Code: Select all

Procedure.l Mod(ivalue.l, ibase.l)
  MOV eax,[esp]           ;grab ivalue.l from the stack (1st item at bottom)
  XOR edx,edx             ;clear the extended DX register
  DIV dword [esp+4]     ;unsigned divide using ibase.l (next on stack)
  MOV eax,edx             ;put remainder (Mod) in EAX register for return 
  ProcedureReturn        ;cause PB to return value found in EAX
EndProcedure

OpenConsole()                ;use console for output
ConsoleColor(15,1)          ;make colors white on blue (more pleasing)
ClearConsole()                ;set all the console to same colors
For a.l=0 To 24                ;create 50 examples of Mod(N,31)
  ConsoleLocate(0,a)        ;position to next line and column
  Print("Mod("+Str(a)+",31) ==> "+Str(mod(a,31)))
  ConsoleLocate (39,a)      ;position to left on same line
  Print("Mod("+Str(a+25)+",31) ==> "+Str(mod(a+25,31)))
Next
While Inkey()=""          ;wait until a key is pressed, then terminate
Wend
has-been wanna-be (You may not agree with what I say, but it will make you think).
Soulfire
User
User
Posts: 23
Joined: Mon Mar 08, 2004 7:17 am

Post by Soulfire »

Any language has (or ..should.. have) a modulus operator, and PB is no exception. It is documented in the ..you guessed it.. "Variables, Types, and Operators" page. Wow, imagine that.
User avatar
blueznl
PureBasic Expert
PureBasic Expert
Posts: 6166
Joined: Sat May 17, 2003 11:31 am
Contact:

Post by blueznl »

this is where the not will one day be inluded, not?

:-)
( PB6.00 LTS Win11 x64 Asrock AB350 Pro4 Ryzen 5 3600 32GB GTX1060 6GB)
( The path to enlightenment and the PureBasic Survival Guide right here... )
Kris_a
User
User
Posts: 92
Joined: Sun Feb 15, 2004 8:04 pm
Location: Manchester, UK

Post by Kris_a »

blame Microsoft, their CHM format doesn't seem to support special characters (=,!,~,<,>,(,),%) in the search section :roll:
dontmailme
Enthusiast
Enthusiast
Posts: 537
Joined: Wed Oct 29, 2003 10:35 am

Post by dontmailme »

blueznl wrote:this is where the not will one day be inluded, not?

:-)
You are not not right about not being not not included at some stage, or not ?!

:lol:
Paid up PB User !
TronDoc
Enthusiast
Enthusiast
Posts: 310
Joined: Wed Apr 30, 2003 3:50 am
Location: 3DoorsDown

Post by TronDoc »

Kris_a wrote:blame Microsoft, their CHM format doesn't seem to support special characters (=,!,~,<,>,(,),%) in the search section :roll:
WinDoze'98fe's "find" function can't search for a '$' as
text to find in files... :roll:
Dr. Dri
Enthusiast
Enthusiast
Posts: 243
Joined: Sat Aug 23, 2003 6:45 pm

Post by Dr. Dri »

Code: Select all

Procedure.w Mod(value1.w,base1.w)
temp1.w
     MOV ax,value1
     XOR dx,dx
     DIV base1
     MOV temp1,dx
     ProcedureReturn temp1
EndProcedure 
Debug Mod(8, 0)
PB hasn't always had a modulus operator... So this is how i used to do :

Code: Select all

procedure mod(a, b)
  if b=0
    ;if b=0 a/b is forbidden
    ;so i don't divide
    procedurereturn a
  endif
  a=a-a/b*b
  procedurereturn a
endprocedure
Dri ;)
User avatar
Michael Vogel
Addict
Addict
Posts: 2797
Joined: Thu Feb 09, 2006 11:27 pm
Contact:

Re: The MOD() Function

Post by Michael Vogel »

What is the best way (except a native PB function) to get a quick and precise solution for doubles?

Results like 0.90000009536743 for the code below are not absolute perfect...

Code: Select all

Procedure.f Mod(x.f, y.f)
	!FLD  dword [p.v_x]
	!FLD  dword [p.v_y]
	!FPREM
	!FSTP st1
	!RET  8
EndProcedure
Post Reply