News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

the random of floating point data

Started by six_L, September 18, 2024, 02:13:27 AM

Previous topic - Next topic

six_L

Hi,all
FP10 MACRO value
        LOCAL vname
        .data
        align 8
        vname REAL10 value
        .code
        EXITM <vname>
ENDM

randf proc @Fmax:QWORD,@Fmin:QWORD
LOCAL num:REAL8
LOCAL @rdx:QWORD

mov @rdx,rdx

finit
fld tbyte ptr [rcx] ;Fmax
fld tbyte ptr [rdx] ;Fmin
fsub ;st0= Fmax-Fmin

invoke iRand, 0, 0000FFFFFFFFFFFFFh
mov       rcx,03FF0000000000000h
or rax,rcx
mov num,rax

fld num ;[1.0-2.0)
fld1
fsub ;[0.0-1.0)

fmul ;[0.0-1.0)*(Fmax-Fmin)
mov rdx,@rdx
fld tbyte ptr [rdx] ;Fmin
fadd ;[0.0-1.0)*(Fmax-Fmin) + Fmin
ret

randf endp

1. the above codes can create the random(REAL8) of floating point data. it's faster six times than some codes who used the "FDIV" instructs.
i used the " GdipDrawEllipse " API to test its result well. The x y(REAL4) coordinates of every little circle is the random of floating point data.
as the following png.
2. How to use
    local x11:REAL4
    local y11:REAL4
    local Fmin:REAL10
    local Fmax:REAL10
       
    finit
    fld    FP10(-3.2)
    fstp    Fmin
    fld    FP10(6.12)
    fstp    Fmax
    invoke  randf,addr Fmax,addr Fmin        ;st0=[@Fmin,@Fmax)
    fstp    x11
3. do you know the other method without "FDIV", that can create a random of floating point data?
Say you, Say me, Say the codes together for ever.

six_L

nobody dispute it, I assume it's correct, goto next.
Comparison of Floating Point Data:
  if |fv_1 - fv_2| > eps, then
    {
    if (fv_1 - fv_2) > 0, then
        fv_1 > fv_2;
    if (fv_1 - fv_2) < 0, then
        fv_1 < fv_2;
    };
   if |fv_1 - fv_2| =< eps, then
    {
    fv_1 = fv_2;
    };
eps: The precision of error which you need to control
FpuComp proc lpSrc1:QWORD, lpSrc2:QWORD, lpEps:QWORD
    LOCAL content[136] :BYTE
    LOCAL diffFlag :BOOL

    fsave content
    jmp   src2            ;Src1
srcerr:
    frstor content
srcerr1:
    xor   rax,rax           ;error code
    ret
;----------------------------------------
;load lpSrc2 to FPU
;----------------------------------------
src2:
    mov   rax,lpSrc2
    fld   tbyte ptr [rax]
     
;----------------------------------------
;load lpSrc1 to FPU
;----------------------------------------
src1:
    mov   rax,lpSrc1
    fld   tbyte ptr [rax]

    fsub
   
    ftst            ;compare the value of ST(0) to +0.0
    fstsw ax        ;copy the Status Word containing the result to AX
    fwait            ;insure the previous instruction is completed
    sahf            ;transfer the condition codes to the CPU's flag register
    jpe srcerr        ;the comparison was indeterminate
                ;this condition should be verified first
                ;then only two of the next three conditional jumps
                ;should become necessary, in whatever order is preferred,
                ;the third jump being replaced by code to handle that case
    ja   st0_positive    ;when all flags are 0
    jb   st0_negative    ;only the C0 bit (CF flag) would be set if no error
    ;jz   st0_zero        ;only the C3 bit (ZF flag) would be set if no error   
st0_positive:
    mov diffFlag,TRUE
    jmp @F
st0_negative:
    mov diffFlag,FALSE
@@:
    fabs
   
;----------------------------------------
;load lpEps to FPU
;----------------------------------------
    mov   rax,lpEps
    fld   tbyte ptr [rax]

    fxch
    fcom
    fstsw ax                ;retrieve exception flags from FPU
    fwait
    shr   al,1              ;test for invalid operation
    jc    srcerr            ;clean-up and return result
    sahf                    ;transfer to the CPU flags
    jpe   srcerr            ;error if non comparable
    ja    greater
    jc    smaller
    mov   rax,CMP_EQU       ;|Src1-Src2| = eps
    jmp   finish

smaller:
    mov   rax,CMP_EQU    ;|Src1-Src2| < eps
    jmp   finish

greater:            ;|Src1-Src2| > eps
    .if    diffFlag == TRUE
        mov   rax,CMP_LOWER     ;Src1 < Src2
    .else
        mov   rax,CMP_GREATER   ;Src1 > Src2
    .endif

finish:
    frstor content
    ret
   
FpuComp endp

WorkerThread proc USES rbx rsi rdi Parameters:QWORD
    LOCAL szfV_1[40]:BYTE
    LOCAL szfV_2[40]:BYTE
    LOCAL szBuf[128]:BYTE
    LOCAL fIn:REAL10
    LOCAL fV_1:REAL10
    LOCAL fV_2:REAL10
    LOCAL Fmax:REAL10
    LOCAL Fmin:REAL10
    LOCAL Feps:REAL10
   
    finit   
   
    fld    FP10(-0.01)
    fstp    Fmin
    fld    FP10(0.015)
    fstp    Fmax

    invoke  randf,addr Fmax,addr Fmin        ;st0=[@Fmin,@Fmax)
    fstp    fV_1
    invoke  randf,addr Fmax,addr Fmin        ;st0=[@Fmin,@Fmax)
    fstp    fV_2
       
    ;Print

    fld    fV_1
    fstp    fIn
    invoke    RtlZeroMemory,ADDR szfV_1,sizeof szfV_1
    invoke    FpuFLtoA64,addr fIn,15, ADDR szfV_1, SRC1_REAL or STR_REG

    fld    fV_2
    fstp    fIn
    invoke    RtlZeroMemory,ADDR szfV_2,sizeof szfV_2
    invoke    FpuFLtoA64,addr fIn,15, ADDR szfV_2, SRC1_REAL or STR_REG

    invoke    RtlZeroMemory,ADDR szBuf,sizeof szBuf
    fld    FP10(0.001)
    fstp    Feps

    invoke    FpuComp,ADDR fV_1,ADDR fV_2, addr Feps
    .if    rax == CMP_EQU
        invoke    wsprintf,addr szBuf,CStr("result: ( %s )  =  ( %s )"),addr szfV_1,addr szfV_2
    .elseif rax == CMP_GREATER
        invoke    wsprintf,addr szBuf,CStr("result: ( %s )  >  ( %s )"),addr szfV_1,addr szfV_2
    .elseif rax == CMP_LOWER
        invoke    wsprintf,addr szBuf,CStr("result: ( %s )  <  ( %s )"),addr szfV_1,addr szfV_2
    .else
        invoke    wsprintf,addr szBuf,CStr("result: ( %s )"),CStr("Unknown Error!!!")
    .endif
    invoke    AddLog,addr szBuf
    invoke    AddLog,CStr(13,10,"--------------------------------------------------------------------------------------------",13,10)

    ret

WorkerThread endp
Say you, Say me, Say the codes together for ever.