Hacking Need help withprogram math, i dumb

  • Thread starter Thread starter scooby74029
  • Start date Start date
  • Views Views 1,699
  • Replies Replies 19
  • Likes Likes 1

scooby74029

Copy and Paste Developer
Member
Joined
May 7, 2010
Messages
1,533
Reaction score
483
Trophies
2
Age
50
Location
oklahoma, USA
Website
www.wiithemer.org
XP
2,486
Country
United States
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 !!!!
 
  • Like
Reactions: portugeek
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 :P
 
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
 
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).
 
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).


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
 
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
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.
 
  • Like
Reactions: scooby74029
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.
 
  • Like
Reactions: scooby74029
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
 
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).
 
  • Like
Reactions: scooby74029
@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.
 
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.
Of course. This is a much simpler and cleaner solution.
ok ill try it out thanks again sifjar
ok that is working better but does it matter that numchunks is a u32
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.
 
  • Like
Reactions: scooby74029
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

So, if FilesLoaded == 3;

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

In other words:
Y == 100/TotalFiles*FilesLoaded; //Current percentage of loaded files

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.
 
Uhm... isn't this basic maths though?
Y == 100/TotalFiles*FilesLoaded; //Current percentage of loaded files
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"
 

Site & Scene News