Author Topic: rnd(a,b) command?  (Read 8352 times)

0 Members and 2 Guests are viewing this topic.

Aurel

  • Guest
Re: rnd(a,b) command?
« Reply #15 on: April 11, 2013, 12:50:42 AM »
I try..
compile Ok
but when i run program after few message boxes ,program just crush ???

Aurel

  • Guest
Re: rnd(a,b) command?
« Reply #16 on: April 11, 2013, 04:03:27 AM »
Finally.. it work fine :)
i do what Peter say ,so i call Randomize() inside function Rand(min,max)
Code: [Select]
! GetTickCount Lib "kernel32.dll" () as sys
sys seed

Function Randomize() as sys
    seed = GetTickCount
End Function

Function Rand(sys z1,z2) as sys
Randomize
    pushad
    sys  rnd
    mov  eax,z2
    sub  eax,z1
    inc  eax
    imul edx,seed,0x8088405
    inc  edx
    mov  seed,edx
    mul  edx
    add  edx,z1
    mov  rnd,edx
    popad
    Return rnd
End Function

print Rand(1,100)

I am wondering is this posible to write without asm code?

Frankolinox

  • Guest
Re: random(a,b) with arrays :)
« Reply #17 on: April 11, 2013, 04:35:02 AM »
1) here's my fixed version for random(a,b) with arrays :-)

that's only "one possible" approach for this task and this works fine here..

Code: [Select]
'
'random test with arrays by frankolinox for oxygenbasic, 11.april.2013
'

print "..new random(a,b) test follows.."
'-----------------------// test // ------------------
function rando(sys*max,sys*min) as long
    '------------- max    
    sys p=@max
        rdtsc
        cdq
        idiv max
        cmp edx, 0
        jge after
        neg edx
    .after:
        mov edx,p        
    return [edx+4] 'max    'that's I fixed ;)
    
    '------------- min    
    sys k=@min
        rdtsc
        cdq        
        idiv min
        cmp edx, 0
        jge after
        neg edx
    .after:        
        mov edx,k
    return [edx+4]
    
end function

indexbase 0

sys aa[12]={100,200,300,400,500,600,700,800,900,1000,1100,1200}
sys ab[31]={10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30}

print "test random function with arrays"
print "ok"
print rando aa[2] ,aa[4] 'result: 400 for indexbase 0
print "ok2"
print rando ab[3] ,ab[5] 'result: 14 for indexbase 0
print "ok3"


2) I am not sure, but I think that's peter example serves with no different values as random function should do. output gives in that example only first parameter back and not different (random) values.

best regards, frank
« Last Edit: April 11, 2013, 04:45:00 AM by Frankolinox »

Emil_halim

  • Guest
Re: rnd(a,b) command?
« Reply #18 on: April 11, 2013, 07:08:51 AM »
Hi Frank,

My i ask you a question .

why you do the job towis , one for max value and other one for min.

for the sake of speed , you can do only one time for a value (max-min) then add min to the result.

here is the example again
Code: [Select]
int Rnd(int max)
{
   int a;
 
      rdtsc          ; call read time-stamp counter instruction
                     ; returns timer value in edx:eax
      cdq            ; convert double word to quad word
                     ; edx:eax <-- sign extension of EAX
      idiv max       ; divide edx:eax by max integer
                     ; stores result in EAX <- Quotient, EDX <- Remainder
                     ; EDX = edx:eax % max
      cmp edx, 0     ; compare value to zero?
                     
      jge after      ; jump if not less than to after: label
      neg edx        ; otherwise, change sign to positive
.after:
      mov a, edx     ; store random number in a
 
   return a;      // return random number
}

macro RndA(min,max)
  rnd(max-min)+min
end macro
       

Emil_halim

  • Guest
Re: rnd(a,b) command?
« Reply #19 on: April 11, 2013, 07:56:44 AM »
Hi Peter,

yes , jge is equal to jnl.

but Oxygen did not support jnl and many of jn... and i have told Mr Charles.

he will complete it.  

Frankolinox

  • Guest
Re: rnd(a,b) command?
« Reply #20 on: April 11, 2013, 10:25:38 AM »
@emil: the macro didn't work here this morning, I don't know why. therefore I tried another way. in this example I adept little for oxygen everything is working fine, I used instead of macro a function. your example didn't work for me at all, so I was searching for another way. now I have installed newer oxygen update and everything is going well and much better. the little devil hides in some details how so often ;)

Code: [Select]
$ filename "rnd2a.exe"
#include "inc\RTL32.inc" '#include "..\..\inc\RTL32.inc"

function rnd(int max) 
   int a
   rdtsc
   cdq
   idiv max
   cmp edx, 0
   jge after
   neg edx
.after:     
   mov a, edx 
return a        '[edx+4]
end function
'------------------- macro doesnt work here correctly ----- //
macro RndAll(min,max) 
rnd(max-min)+min
end macro

'print RndAll(200,300) 'unidentified array or procedure error message!

'------------------- macro doesnt work here correctly ----- //

print "ok"


function rndAllgo(int min,max) 'function works fine!
   return rnd(max-min)+min
end function

print "randomFunction 200-300: " +str(RndAllgo(200,300))

print "first: "+str(Rnd(100))
print "second: "+str(Rnd(500))

print "end of random example"

I am glad that's all working.

@peter: your example is working for me too. don't ask me why, I suppose it's belonging to an old oxygen.dll or my notebook has got a cold ;)

frank

Aurel

  • Guest
Re: rnd(a,b) command?
« Reply #21 on: April 11, 2013, 12:58:14 PM »
Yeah Peter , Randomize ONCE -> work whole day.. ;D

Emil...
Because you like to add comments ,do you can comment this Peter code
for laics like me that will be interesting..
Code: [Select]
Function Rand(sys z1, z2) as sys
    sys    rnd
    mov    eax,z2   ; move z2 to eax
    sub    eax,z1    ; subtract eax - z1
    inc    eax         ; increase eax
    imul   edx,sys_Seed,0x8088405  ; i(what? multiply / you can kill me if i know what is this /)
    inc    edx
    mov    sys_Seed,edx
    mul    edx
    add    edx,z1
    mov    rnd,edx
    return rnd
End Function


Heh ...i just try.. :-\

Charles Pegge

  • Guest
Re: rnd(a,b) command?
« Reply #22 on: April 11, 2013, 08:05:05 PM »
I don't understand exactly how this algorithm works, except that the edx register is overwritten when a 32 bit multiply is performed.  edx takes the upper 32 bits of the product (bits 32..63). so it is rather specific to x86 processors. Very clever though.

http://www.illmob.org/Sources/RobinHood.html

Emil_halim

  • Guest
Re: rnd(a,b) command?
« Reply #23 on: April 12, 2013, 03:46:29 AM »
Aurel ,

here is the comments

first i will demonstrate it then adding the comments.
Quote
we have a Sys_seed variable that holds the returned value of Randomize function , it get a semi random value because it return the timer at any time.

we subtract min value from max value and add 1 to  result . then we multiply this result by 0x8088405
then increasing it by 1 , we store it for next calling, add it to min value and return the rand value.     
 
this is the concept of this code
   

here is the comments
Code: [Select]
Function Rand(sys z1, z2) as sys
    sys    rnd
    mov    eax,z2   ;  Eax = max value
    sub    eax,z1    ;  Eax = eax - min value
    inc    eax         ;  Eax = Eax + 1
    imul   edx,sys_Seed,0x8088405 ; edx = Sys_seed * 0x8088405
    inc    edx
    mov    sys_Seed,edx ; Sys_seed = EDX
    mul    edx                ; Eax = Eax * edx 
    add    edx,z1            ; eax = eax + min value
    mov    rnd,edx         ; rnd = eax
    return rnd               
End Function



Charles Pegge

  • Guest
Re: rnd(a,b) command?
« Reply #24 on: April 12, 2013, 04:51:25 AM »
What I don't understand is how the result is confined within the upper range. Any ideas Emil, Peter?

Emil_halim

  • Guest
Re: rnd(a,b) command?
« Reply #25 on: April 12, 2013, 05:15:11 AM »
hi Charles,

consider the following
Quote
 
    imul op1 , op2 , imm 
eg.
    imul edx , ecx , 100   
will be
   (32 bit) edx  = (32 bit) ecx * 100

that is deffer from this
   mul op
eg.
   mul ebx
will be
   Edx:Eax = Eax * Ebx         ------------ here edx is the upper result.   


Emil_halim

  • Guest
Re: rnd(a,b) command?
« Reply #26 on: April 12, 2013, 05:21:41 AM »
Aurel ,

here is Peter's code with High Level asm , may be better to understand
Code: [Select]
===============================
' Peter's function with HLA
===============================
Function H_Rand(sys z1,z2) as sys
    ^  eax =  z2
    ^  eax -= z1
    ^  eax++
    ^  edx = seed * 0x8088405
    ^  edx++
    ^  seed =  edx
    ^  eax *=  edx
    ^  edx +=  z1
    ^  eax >< edx
    Return eax
End Function

BTW i have made a litle change

Emil_halim

  • Guest
Re: rnd(a,b) command?
« Reply #27 on: April 12, 2013, 06:23:06 AM »

Hi Peter

Quote
machine code isn't that easy, but for an Engineer is it easy.

BTW , I am Engineer , but civil Engineer .  :)

 

Aurel

  • Guest
Re: rnd(a,b) command?
« Reply #28 on: April 12, 2013, 08:22:47 AM »
Heh ..i try to convert Emil comments to pure Basic code
but it looks that i mess up ::)
Code: [Select]
'random basic
! GetTickCount Lib "kernel32.dll" () as sys
sys sys_Seed

Sub Randomize()
    sys_Seed = GetTickCount
End Sub

Function Rand(sys z1, z2) as sys
Randomize()
sys rnd,ex,ed
  ex = z2
  ex = ex-z1
  ex = ex+1
  ed = sys_Seed * 0x8088405
  ed = ed+1
  sys_Seed = ed
  ex = ex * ed
  ex = ex + z1
  rnd = ex
    return rnd
End Function

print Rand(1,100)

Emil do you can fix this..?

Emil_halim

  • Guest
Re: rnd(a,b) command?
« Reply #29 on: April 12, 2013, 08:55:08 AM »
Aurel ,

the problem is here
Quote

^  eax *=  edx

this translated to that

Mul edx

so this asm instruction is better to presented like that

 (64 bits) Edx:Eax = Eax * edx

then edx is the high Dowrd of the quad multiplication 


in your basic code you took the lower Dword of  quad multiplication.

really i do not know how to make it by basic