I keep forgetting the fact that PB is retarded when it comes to the modulo operator and floating point values!.
It’s time to write our own fmod() equivalent; lucky for us the Intel guys were kind enough as to implement quite a useful instruction called FPREM a few eons ago, which pretty much means “Partial REMinder” and what it does is rather simple: it computes the partial remainder of st(0)/st(1).
Procedure.f fmod( x.f, y.f )
EnableASM
FLD DWORD[p.v_y]
FLD DWORD[p.v_x]
!NOT_READY:
FPREM
FSTSW AX
TEST AH, 100b
!JNZ NOT_READY
FSTP ST1
DisableASM
ProcedureReturn
EndProcedure
Of course with great instructions comes great limitations: in this case we cannot produce the final reminder if the difference between X and Y is bigger than 63. We can solve this by implementing a loop and checking for the C2 bit of the status word to be cleared. This is all explained in the IA32 manuals.
It’s not pretty but until fpu modulo operations are officially supported in the language, this might well be your only sane choice.
Thanks! I thought there was no way of doing this in pure basic. I cant read assembler but I will definitely use this.
Could you explain me what the code does though?
No problem. It’s Assembly though, assembler would be the compiler itself. You can ask Intel for the IA32 manuals, they’re free. Or just download the PDFs from their site.
The code is almost entirely taken from a manual. First we load X and Y onto the stack, We then loop until the control flag is cleared. So if the result of TEST is not zero (JNZ), we jump onto the label that we previously declared. We finally pop and we return.
FSTSW is simply used to get the condition bits into AX.
You may test the routine like so:
Cheers.