Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Divide by 6 using C and avoiding floating point?

Status
Not open for further replies.

blueroomelectronics

Well-Known Member
I'm doing a dice program using a freerunning timer that automatically and fairly counts from 0-6^x (where x is number of die)
Now one die is easy (I'm a BASIC programmer but want to do it in C18)

So
A single die is roll+1

Two dice are D1=int(roll/6)+1 and D2=(roll mod 6)+1

Any ideas on 3 or more dice? And avoiding floating point...
 
Isn't it just

D1=roll mod 6
D2=(roll/6) mod 6
D3=(roll/36) mod 6
D4=(roll/216) mod 6
etc.

If you do it in integer maths then it should just work.

Mike.
 
Does the MCU you're using have a hardware divide instruction or are you useing a maths library?

The x86 does and puts the quotent and remainder in to different registers. Using a high level language like C will probably end up producing two divide instructions, one to get the remainder and another for the quotent which is a wate of clock cycles. I'd recommend doing the division part in assembler, that way you can use one instruction to get both the quotent and remainder.
 
Hero999 said:
Does the MCU you're using have a hardware divide instruction or are you useing a maths library?

The x86 does and puts the quotent and remainder in to different registers. Using a high level language like C will probably end up producing two divide instructions, one to get the remainder and another for the quotent which is a wate of clock cycles. I'd recommend doing the division part in assembler, that way you can use one instruction to get both the quotent and remainder.

What use is the remainder? For D4 the calculation goes, int(roll/216), result/6 and keep remainder. Two divides required anyway. D2 is the only one that could benefit from the remainder but the additional code wouldn't be worth it.

Mike.
 
I don't see why more than one divider per iteration is required.

Roll is the variable with the the value generated by the timer.

Divide, is the divide instruction, it accepts two variables, the first value is divided by the second value. After the instruction is executed the quotent is stored in the first variable and the remainder is stored in the second.

e.g.

x = 105
y = 10
Divide x, y
Print x, y

The output will be:
10 5

Assuming the PIC has a similar instruction, here's how you'd use it. Roll is the random number which is set before the code runs.

Do
Remainder = 6
Divide Roll, Remainder
Print Remainder
Loop until Roll = 0
 
Well the formula should work well as an unsigned int function (now I'll have to learn C18 functions)
Code:
for Roll = 0 to 6^4-1
D1 = int(Roll/1 mod 6)+1
D2 = int(Roll/6 mod 6)+1
D3 = int(Roll/36 mod 6)+1
D4 = int(Roll/216 mod 6)+1
print Roll, D1, D2, D3, D4
next
Just BASIC program
 
Hero,
I see what you mean now. Doing it in asm would save a divide.

Bill,
In C it would simply be,
Code:
    D2=((Roll/6)%6)+1;
Not much difference really.

Mike.
 
Thanks I always thought % meant binary. But in C it means modulo.

Using special mode the CCP allows TMR1 to be a free running modulo x counter.
 
Last edited:
blueroomelectronics said:
Using special mode the CCP allows TMR1 to be a free running modulo x counter.
Ahh, the special event trigger, one of my favourites.

Mike.
 
Pommie said:
Ahh, the special event trigger, one of my favourites.

Mike.

It's a real gem, it was one of your older posts that pointed it out to me.

It occurred to me to let it free run till you press a button, presto instant random number.
I could do the software in Swordfish easy, but it's more a challenge to do it in C18.

Eventually I'll make a Risk game battle dice (5 dice) roller on the Junebug as one of the tutorials.
 
You can of course use the compiler's runtime library to do the division if the PIC does not have a hardware divider, but if it is just for 2 dice why don't you use repeated substraction in a loop ? Stupid ,yes but very simple and performance is not a concern in this case, anyway the number of iterations would be 0 to 5 so who cares ? This will give you both the result of the division and the remainder... easy to do even in assembly.
Petr
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top