Hello,

I was toying around with the rand function and saw an example in C on the msdn page. The example generates a random number between a lower and a upper boundary. My problem is the conversion of this line:

rand() / RAND_MAX + 1 * (range_max - range_min) + range_min

I have big problems to convert that line of code to ASM. I've searched this msg board and saw a dozen of other rand examples. Those are not relevant for me because i want to play around with the div & mul stuff for this moment.

Can any of you translate the code to ASM for me, thx alot.

Grtz,

Slash0r

I was toying around with the rand function and saw an example in C on the msdn page. The example generates a random number between a lower and a upper boundary. My problem is the conversion of this line:

rand() / RAND_MAX + 1 * (range_max - range_min) + range_min

I have big problems to convert that line of code to ASM. I've searched this msg board and saw a dozen of other rand examples. Those are not relevant for me because i want to play around with the div & mul stuff for this moment.

Can any of you translate the code to ASM for me, thx alot.

Grtz,

Slash0r

Instead of us just doing the work for you...

How far have you gotten with converting this to ASM so far... And what exactly is the thing you got stuck on?

(If I had to guess... the line of code you posted will only work with floating point numbers, because it introduces fractions. You may want to rewrite it to avoid fractions first, something I'd recommend in C/C++ anyway).

How far have you gotten with converting this to ASM so far... And what exactly is the thing you got stuck on?

(If I had to guess... the line of code you posted will only work with floating point numbers, because it introduces fractions. You may want to rewrite it to avoid fractions first, something I'd recommend in C/C++ anyway).

Hi Scali,

I've gotten this far:

call crt_rand ; rand() / RAND_MAX + 1 * (range_max - range_min) + range_min

xor edx, edx

mov ecx, RAND_MAX

inc ecx

div ecx ; eax = quotient, edx = remainder.

Well this was easy ofc. The problem is when the division produces remainders. What should i do with the remainder of the division (multiply it by range_max - range_min as well)? So should i multiply both quotient and remainder with range_max - range_min and add both togehter of something? It's really puzzling for me.

Grtz,

Slash0r

I've gotten this far:

call crt_rand ; rand() / RAND_MAX + 1 * (range_max - range_min) + range_min

xor edx, edx

mov ecx, RAND_MAX

inc ecx

div ecx ; eax = quotient, edx = remainder.

Well this was easy ofc. The problem is when the division produces remainders. What should i do with the remainder of the division (multiply it by range_max - range_min as well)? So should i multiply both quotient and remainder with range_max - range_min and add both togehter of something? It's really puzzling for me.

Grtz,

Slash0r

mov edx,range_max

sub edx,range_min

mul edx

add eax,range_min

We are scaling the value by (max-min), thus putting it in the range (0 thru max-min)... then we are adding min, thus putting it in the range (min thru max) :)

sub edx,range_min

mul edx

add eax,range_min

We are scaling the value by (max-min), thus putting it in the range (0 thru max-min)... then we are adding min, thus putting it in the range (min thru max) :)

The problem here is that rand() / RAND_MAX will basically always result in something between 0 and 1.

You can't do it that way with integer math, because it will just round towards 0.

So you either have to use floating point (which I don't recommend), or you have to rework the mathematics.

For example, if I do this:

((rangemax-rangemin)*rand()) / RAND_MAX

Now it no longer uses fractions, because you scale up first, then you divide, and you end up in the 0..(rangemax-rangemin) range, which fits into an integer just fine.

You can't do it that way with integer math, because it will just round towards 0.

So you either have to use floating point (which I don't recommend), or you have to rework the mathematics.

For example, if I do this:

((rangemax-rangemin)*rand()) / RAND_MAX

Now it no longer uses fractions, because you scale up first, then you divide, and you end up in the 0..(rangemax-rangemin) range, which fits into an integer just fine.

Yeah Scali thats more like it.

Homer is ignoring the remainder of the division, that can't be right :) (but thx anyway for your reply Homer).

I think it's wise to use imul and idiv as well btw.

What to do if we cant get around floating point arithmetic in ASM?

Homer is ignoring the remainder of the division, that can't be right :) (but thx anyway for your reply Homer).

I think it's wise to use imul and idiv as well btw.

What to do if we cant get around floating point arithmetic in ASM?

Well, you can just use floats in asm... you have fadd, fsub, fmul, fdiv and all that.

It's just that it's a bit more difficult to read and write, and generally it will not perform as well for simple operations (especially converting from integer to float and back will generally cost time... and the FPU doesn't have normal registers, it uses a weird stack system to access the registers).

It's just that it's a bit more difficult to read and write, and generally it will not perform as well for simple operations (especially converting from integer to float and back will generally cost time... and the FPU doesn't have normal registers, it uses a weird stack system to access the registers).

especially converting from integer to float and back will generally cost time

That time is quite minimal, unless you have to generate a zillion random numbers without stopping.

@Slash0r

The FPU is not that difficult to use once you know how, specially if it's only for the basic arithmetic operations. If you are seriously interested, spend a bit of time looking at the following:

http://www.ray.masmcode.com/tutorial/index.html

That time is quite minimal, unless you have to generate a zillion random numbers without stopping.

Well... if I didn't care about minimal timing issues, I wouldn't bother to write it in asm in the first place ;)

Oldest discussion in the asm world.