Page 1 of 1
The MOD() Function
Posted: Thu Apr 15, 2004 10:32 pm
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
Posted: Thu Apr 15, 2004 11:00 pm
by freak
Why don't you use the PB mod ( % ) operator?
Timo
Posted: Thu Apr 15, 2004 11:17 pm
by dontmailme
Another example
Posted: Thu Apr 15, 2004 11:45 pm
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
Posted: Fri Apr 16, 2004 11:27 am
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.
Posted: Fri Apr 16, 2004 12:35 pm
by blueznl
this is where the not will one day be inluded, not?

Posted: Fri Apr 16, 2004 12:43 pm
by Kris_a
blame Microsoft, their CHM format doesn't seem to support special characters (=,!,~,<,>,(,),%) in the search section :roll:
Posted: Fri Apr 16, 2004 2:29 pm
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 ?!

Posted: Sat Apr 17, 2004 11:43 am
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:
Posted: Tue Jun 15, 2004 1:34 pm
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

Re: The MOD() Function
Posted: Tue Dec 15, 2009 7:02 pm
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