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?

Code: Select all

a = 7
b = 4
Debug a % b
Timo

Posted: Thu Apr 15, 2004 11:17 pm
by dontmailme
:lol:

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

:lol:

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 ?!

:lol:

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