Hacking Need help withprogram math, i dumb

scooby74029

wanttabe dev
OP
Member
Joined
May 7, 2010
Messages
1,357
Trophies
1
Age
48
Location
oklahoma, USA
Website
www.wiithemer.org
XP
1,322
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

SifJar

Not a pirate
Member
Joined
Apr 4, 2009
Messages
6,022
Trophies
0
Website
Visit site
XP
1,175
Country
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
 

scooby74029

wanttabe dev
OP
Member
Joined
May 7, 2010
Messages
1,357
Trophies
1
Age
48
Location
oklahoma, USA
Website
www.wiithemer.org
XP
1,322
Country
United States
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
 

SifJar

Not a pirate
Member
Joined
Apr 4, 2009
Messages
6,022
Trophies
0
Website
Visit site
XP
1,175
Country
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

wanttabe dev
OP
Member
Joined
May 7, 2010
Messages
1,357
Trophies
1
Age
48
Location
oklahoma, USA
Website
www.wiithemer.org
XP
1,322
Country
United States
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
 

SifJar

Not a pirate
Member
Joined
Apr 4, 2009
Messages
6,022
Trophies
0
Website
Visit site
XP
1,175
Country
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

smealum

growing up sucks.
Member
Joined
May 1, 2006
Messages
635
Trophies
2
Age
31
Location
SF
Website
www.smealum.net
XP
2,515
Country
United States
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

Supercool330

Well-Known Member
Member
Joined
Sep 28, 2008
Messages
752
Trophies
1
XP
1,129
Country
United States
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

scooby74029

wanttabe dev
OP
Member
Joined
May 7, 2010
Messages
1,357
Trophies
1
Age
48
Location
oklahoma, USA
Website
www.wiithemer.org
XP
1,322
Country
United States
@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.
 

SifJar

Not a pirate
Member
Joined
Apr 4, 2009
Messages
6,022
Trophies
0
Website
Visit site
XP
1,175
Country
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

Foxi4

Endless Trash
Global Moderator
Joined
Sep 13, 2009
Messages
30,824
Trophies
3
Location
Gaming Grotto
XP
29,819
Country
Poland
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.
 

PsyBlade

Snake Charmer
Member
Joined
Jul 30, 2009
Messages
2,204
Trophies
0
Location
Sol III
XP
458
Country
Gambia, The
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

Popular threads in this forum

General chit-chat
Help Users
  • No one is chatting at the moment.
    Psionic Roshambo @ Psionic Roshambo: https://m.youtube.com/watch?v=lDRjqI-fBVI&pp=ygUPVml0Z2luIG1hZ2ljaWFu