# PHP / Maths problem

#### Tom743

##### New Member
Basically, the average for the number of rolls on my script isn't working. It keeps going up, until it gets higher than 6 which is impossible because the numbers generated are between 1 and 6. I will +rep anyone who can help me PHP:
``````<?php
\$number = rand("1", "6");
\$numberofroll = file_get_contents("roll.txt") + 1;
\$average = file_get_contents("average.txt");
\$averagevote = \$average + \$number / \$numberofroll;

\$file = "roll.txt";
\$write = fopen(\$file, "w");
fwrite(\$write, \$numberofroll);
fclose(\$write);

\$file = "average.txt";
\$write = fopen(\$file, "w");
fwrite(\$write, \$averagevote);
fclose(\$write);

echo "You rolled {\$number}. The average number is {\$averagevote}";
?>``````

EDIT: I forgot to say- avarage.txt has the current average roll in, and roll.txt has the number of rolls made in it.

Last edited:

#### TechAsh

##### Retired
I'm not very good with PHP, but I think I've worked out what you are doing and therefore what you are doing wrong.

You are taking the previous average from the file then adding the current roll to it, then dividing by the number of rolls.
What I think you should be doing is keeping a list of what is rolled each time, then adding up all the numbers in that list and dividing by the number of rolls.

Example:
I think you are doing something like this:
Previous rolls: 1,2,3,4
Average: 2.5 (10 / 4)
But if you store 2.5 in the file next time you take an average this would happen:
Previous Average: 2.5
Next Roll: 5
Sum: 2.5 + 5 / 5 = 1.5
This is wrong because:
All Rolls: 1,2,3,4,5
Average: 15 / 5 = 3

Do you get what I mean?

Last edited:

#### Tom743

##### New Member
I'm not very good with PHP, but I think I've worked out what you are doing and therefore what you are doing wrong.

You are taking the previous average from the file then adding the current roll to it, then dividing by the number of rolls.
What I think you should be doing is keeping a list of what is rolled each time, then adding up all the numbers in that list and dividing by the number of rolls.

Example:
I think you are doing something like this:
Previous rolls: 1,2,3,4
Average: 2.5 (10 / 4)
But if you store 2.5 in the file next time you take an average this would happen:
Previous Average: 2.5
Next Roll: 5
Sum: 2.5 + 5 / 5 = 1.5
This is wrong because:
All Rolls: 1,2,3,4,5
Average: 15 / 5 = 3

Do you get what I mean?

Yeah, I get what you mean, thanks I was thinking of doing it it like that but I thought it will take a long time to execute because there could be hundreds of numbers to add up and devide.

#### TechAsh

##### Retired
The problem is that you can't always cut corners in Maths.

#### cerbere

##### New Member
Better do it this way if you don't want to keep the list of
individual rolls in your file : use a weighted sum.

Pseudo-
Code:
``````read current_avg, current_n_of_rolls, this_roll

new_n_of_rolls = current_n_of_rolls + 1
new_avg = (current_avg * current_n_of_rolls + this_roll) / new_n_of_rolls

write new_avg, new_n_of_rolls``````
The problem with your original script was that
Code:
``\$averagevote*=*\$average*+*\$number*/*\$numberofroll;``
can only grow, blasting through 6.

#### quantum1

##### New Member
I believe you want the files to store the number of rolls so far and the grand total of all rolls so far. You can compute the running average as the grand total of all rolls divided by the total number or rolls (values obtained from the files). You can present the average to the user when showing them their roll. You then add 1 to the total number of rolls and add their roll value to the grand total of all rolls, ready to be used the next time. Example shown below, columns may not line up but you get the idea:
Roll # Rolls Total Average
5 1 5 5
3 2 8 4
1 3 9 3
6 4 15 3.25
4 5 19 3.8

#### mattura

##### Member
Yep, the weighted average suggested by cerbere and quantum1 is the way to cut the corner (cos sometimes you can).

To clarify quantum1's example here is another with more symbols :
imagine rolls 1,5,3,4,2... (average 3)
each time, you count how many rolls have occurred, and get the number of the roll. Multiply the average by the number of rolls, add the new roll, then divide by the total plus one.
Roll 1: (x*0 +1) /1 = 1 //x can be any number initially Roll 2: (1*1 +5) /2 = 3
Roll 3: (3*2 +3) /3 = 3
Roll 4: (3*3 +4) /4 = [13/4]
Roll 5: ([13/4]*4 +2) /5 =3
...

#### quantum1

##### New Member
Thanks for the question and everyone's involvement. This reminds me of some areas at work where I can use some running averages to compare systems, response times, etc. This is a cool forum. 