# Need help withprogram math, i dumb

Discussion in 'Wii - Hacking' started by scooby74029, Apr 21, 2013.

# Need help withprogram math, i dumb

849 Views
1. ### scooby74029"fake coder"

Member
May 7, 2010
oklahoma, USA
ok i am writing a new program for theme installing and i have a progress bar but i cant get the percentage formula right need a little help from one of the REAL coders or a math wiz

here is the code i have but it doesnt work correctly :

Code:
```
DrawFrameStart();
sprintf(txtbuffer, "Installing part %d ... ", (i + 1));
percent += 100/numchunks + ((100/numchunks % numchunks != 0) ? 1 : 0 );
DrawProgressBar(percent, txtbuffer);
DrawFrameFinish();
sleep(2);

```
keep in mind this is in a for(i = 0; i < numchunks;i++) statement in my code
any help would greatly appreciated by my dumdness !!!!

portugeek likes this.
2. ### The Real JdbyeAlways Remember 30/07/08

Member
GBAtemp Patron
The Real Jdbye is a Patron of GBAtemp and is helping us stay independent!

Our Patreon
Mar 17, 2010
Alola
percent = current / max * 100
So it would become:
percent = i / numchunks * 100

3. ### SifJarNot a pirate

Member
Apr 4, 2009
My first guess would be you need to multiply 100/numchunks by (i+1) [or maybe i, otherwise the progress will start at 10%]. Because 100/numchunks will be the progress per chunk, so you need to multiply by (i+1) to get the total progress for the number of chunks completed.

I'm also confused as to the purpose of the second part of the percent statement (the conditional part). I think I get what it's doing (if the percentage increase per chunk is exactly divisible by the number of chunks, it adds 1, otherwise it doesn't), but I don't see why. For example, say there were 12 chunks. 100/12 is 8.333. Assuming numchunks is an int, that'll round to 8. 8 % 12 will give 8. So therefore, it will add nothing. On the other hand, if there were 5 chunks, 100/5 is 20. 20 % 5 would be 0, so 1 would be added to the progress. Why?

EDIT: The Read Jdbye beat to correcting the first part while I expressed my confusion over the second part

4. ### scooby74029"fake coder"

Member
May 7, 2010
oklahoma, USA
ah thanks guys
@sijar i was just trying other formula's from different programs i use as my tutorials nice to see you man been along time
@jdbye i knew it had to be something easy but i am not a real coder so i knew i needed some help

thanks again

5. ### scooby74029"fake coder"

Member
May 7, 2010
oklahoma, USA
ok that didn't work at all the progress bar didn't move at all it just stayed at 0%

6. ### SifJarNot a pirate

Member
Apr 4, 2009
What does your code look like now?

7. ### scooby74029"fake coder"

Member
May 7, 2010
oklahoma, USA
i used the code that jdbye gave from previous post but the percentage never moved

8. ### SifJarNot a pirate

Member
Apr 4, 2009
That's because the two numbers are ints, and i is smaller than numchunks, so i/numchunks will always be rounded to 0 (unless it's 1). You could cast them both as floats, by using code like this:

Code:
`percent = (float) i / (float) numchunks * 100.0;`
(the .0 after 100 is to force it to be a float also). The result will be a float (i.e. percent should be a float variable). If you need to pass the percentage as an int to the DrawProgressBar function, cast it as an int with "(int) percent" instead of "percent".

[This may not be the most efficient/best way to do things, but I do believe it should work].

For the record, this is probably also something to do with the reason your original code wasn't working (i.e. rounding error of some sort).

scooby74029 and Coto like this.
9. ### scooby74029"fake coder"

Member
May 7, 2010
oklahoma, USA

percent is an int in my code should i change it to a float for this to work correctly i never messed with floating numbers in any of the code i have written

10. ### SifJarNot a pirate

Member
Apr 4, 2009
Yes, you should change it to float. Don't worry, it's not all that different to ints, except they take up a bit more memory (which you should bear in mind, especially on a device with limited memory; one float won't make a huge difference, but don't use them unless you have to) and can have decimals.

scooby74029 likes this.
11. ### scooby74029"fake coder"

Member
May 7, 2010
oklahoma, USA
ok ill try it out thanks again sifjar
ok that is working better but does it matter that numchunks is a u32

12. ### smealumgrowing up sucks.

Member
May 1, 2006
SF
using floats should work but it's really unnecessary; while still using only ints (or u32s or whatever), something like this should work just fine : percent=(i*100)/numchunks; (which is just jdbye's formula changed so that integer operations' precision should not be an issue)
if percent ends up being rounded off to the nearest integer you won't really get any additional precision out of using floats, so you might as well not.
of course this is a moot point because using one float is not going to make any difference.

scooby74029 likes this.
13. ### The Real JdbyeAlways Remember 30/07/08

Member
GBAtemp Patron
The Real Jdbye is a Patron of GBAtemp and is helping us stay independent!

Our Patreon
Mar 17, 2010
Alola
percent = i * 100 / numchucks
That should work without requiring floats.
Edit:

scooby74029 likes this.
14. ### scooby74029"fake coder"

Member
May 7, 2010
oklahoma, USA
ok guys i got it to work finally
i forgot to add the last progress bar update to bring total to 100% at end of installation
thanks for all the help really !!!!!!

any mod that reads this may close it thamk you

Member
Sep 28, 2008
The most important thing to remember with integer operations is that all division operations are floored (lowered to the nearest integer).

e.g. 5/2 = 2 and 9/10=0

So 9/10*100 = (9/10)*100 = 0*100 = 0
Where as 9*100/10 = (9*100)/10 = 900/10 = 90

The trick is that division breaks commutativity and associativity. All other arithmetic operations (+,-,*,%) behave normally.

Now lets look at your original formula and figure out what is wrong:
Code:
`percent += 100/numchunks + ((100/numchunks % numchunks != 0) ? 1 : 0 );`
First we need to figure out what it is trying to do. Lets decompose the formula into more basic components. The first part is simply 100/numchunks. If we were in normal math (with at least rational numbers), then percent += 100/numchunks would be sufficient, since 100/numchunks would be the exact percent each chunk is worth.

The second component is attempting to correct for the floor, but it is doing so in a completely nonsensical way. What it is attempting to do is add 1 occasionally to correct for the floor. Imagine the case of numchunks being 3, we want the bar to go 0, 33, 67, 100 instead of 0, 33, 66, 99. As we can see, the points at which we add the ones is definitely dependent on where in the sequence we are providing an obvious reason (besides that it makes no sense) that the correction as given is wrong (it is independent of the progress).

But, let us try to construct a proper correction. We know that between 0 and 100 we will need to add 1 exactly 100%numchunks times, but we need to add them at the correct time. We want to add them each time the fractional part of 100*i/numchunks rolls past .5, but it isn't obvious how we detect this. Since we are looking at fractional parts, we reword the problem in terms of modulus (since we are working with integers), and the problem becomes when does 100*i%numchunks roll past numchunks/2 (exact division here). We can get rid of the exact division using some discrete math triks. We want (all exact math) 100*i%numchunks to roll past (be less than at the previous iteration and greater than or equal to on this iteration) numchunks/2. Since 100*i%numchunks is always an integer (since i is an integer), 100*i%numchunks >= numchunks/2 is equivalent to 100*i%numchunks >= ceil(numchunks/2) is equivalent to 100*i%numchunks >= floor((numchunks+(2-1))/2) or 100*i%numchunks >= floor((numchunks+1)/2).

This is really complicated, and points out why the absolute equation is way preferable to the incremental one, but it is possible. There is a relatively clean form, but it takes a lot more discrete math to prove why it works.

Edit:
So the code I posted missed some cases (iterations being on the same side of half), but new one less than original. I have the working version (in simplified form), but the proof would take me pages to explain.
Oh, just to be clear, since we are in C, division isn't actually floored it is truncated (which makes it a lot more complicated).

scooby74029 likes this.
16. ### scooby74029"fake coder"

Member
May 7, 2010
oklahoma, USA
@supercool330
thanks for the explanation i was hoping some one would explain why what i did wasn't working. I taught myself to code over the past 3 yrs when i get time because i think it is fun messing with the wii and making this kind of stuff.

17. ### SifJarNot a pirate

Member
Apr 4, 2009
Of course. This is a much simpler and cleaner solution.
u32 is the same as int except unsigned, I believe. (ints are, unless explicitly declared, usually assumed by the compiler to be signed). "u32" is the same as "unsigned int". signed means that the variable can have a positive or negative value, so 1 of the 32 bits is assigned to holding the sign (+/-), leaving only 31 bits to hold the actual value. Unsigned variables have no sign bit, so all 32 bits can be used to store the actual value. This means the value of an unsigned variable can be twice as large as the value of a signed variable of the same type.

scooby74029 likes this.
18. ### Foxi4On the hunt...

Reporter
Sep 13, 2009
Gaming Grotto
Uhm... isn't this basic maths though?

Say, you have 5 files to load and you use standard loading from FAT, upon loading each file, you increase a variable, then you count and display the percentage floored (so that you don't have to bother with floats)?

The maths part:
5 files = 100
X files = Y
Y = 100/5*X

Y == 100/5*3; //= 60 per cent

In other words:

If you want to be more accurate than that, you can use filesize instead of the number of files. In any case, at the beginning of loading, you know exactly how much you need to load.

scooby74029 and Psionic Roshambo like this.

Member
Jul 30, 2009
Sol III
basic math doesn't take into account the various inaccuracies the different number representations have
since we are talking int here:
consider 3 of 3 parts
100/3*3 in int is really floor(100/3)*3 = 33*3 = 99

as other said: 100*FilesLoaded/TotalFiles is the right formula
100*3/3 makes floor(100*3/3) = floor(300/3) = floor(100) = 100

float by the way is even worse than int
they are not exact
-> unless you really know what you are doing you should never compare two floats with "x == y"
always use: "abs(x-y) < somethingsmall"

20. ### SifJarNot a pirate

Member
Apr 4, 2009
fabsf(x-y)...etc

abs() works of ints, fabs() works on doubles, fabsf() works on floats [fabs and fabsf are both declared in math.h, abs is declared in stdlib.h]

Similar Threads - Need help withprogram