Need help withprogram math, i dumb

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

Apr 21, 2013
  1. scooby74029
    OP

    Member scooby74029 "fake coder"

    Joined:
    May 7, 2010
    Messages:
    1,174
    Location:
    oklahoma, USA
    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 !!!!
     
    portugeek likes this.
  2. The Real Jdbye

    Member The Real Jdbye D:

    Joined:
    Mar 17, 2010
    Messages:
    8,582
    Location:
    Doing your mom
    Country:
    Norway
    percent = current / max * 100
    So it would become:
    percent = i / numchunks * 100
     
  3. SifJar

    Member SifJar Not a pirate

    Joined:
    Apr 4, 2009
    Messages:
    6,022
    Country:
    United Kingdom
    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
     
  4. scooby74029
    OP

    Member scooby74029 "fake coder"

    Joined:
    May 7, 2010
    Messages:
    1,174
    Location:
    oklahoma, USA
    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
     
  5. scooby74029
    OP

    Member scooby74029 "fake coder"

    Joined:
    May 7, 2010
    Messages:
    1,174
    Location:
    oklahoma, USA
    Country:
    United States
    ok that didn't work at all the progress bar didn't move at all it just stayed at 0%
     
  6. SifJar

    Member SifJar Not a pirate

    Joined:
    Apr 4, 2009
    Messages:
    6,022
    Country:
    United Kingdom
    What does your code look like now?
     
  7. scooby74029
    OP

    Member scooby74029 "fake coder"

    Joined:
    May 7, 2010
    Messages:
    1,174
    Location:
    oklahoma, USA
    Country:
    United States
    i used the code that jdbye gave from previous post but the percentage never moved
     
  8. SifJar

    Member SifJar Not a pirate

    Joined:
    Apr 4, 2009
    Messages:
    6,022
    Country:
    United Kingdom
    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
    OP

    Member scooby74029 "fake coder"

    Joined:
    May 7, 2010
    Messages:
    1,174
    Location:
    oklahoma, USA
    Country:
    United States

    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. SifJar

    Member SifJar Not a pirate

    Joined:
    Apr 4, 2009
    Messages:
    6,022
    Country:
    United Kingdom
    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
    OP

    Member scooby74029 "fake coder"

    Joined:
    May 7, 2010
    Messages:
    1,174
    Location:
    oklahoma, USA
    Country:
    United States
    ok ill try it out thanks again sifjar
    ok that is working better but does it matter that numchunks is a u32
     
  12. smealum

    Member smealum growing up sucks.

    Joined:
    May 1, 2006
    Messages:
    627
    Location:
    SF
    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.
     
    scooby74029 likes this.
  13. The Real Jdbye

    Member The Real Jdbye D:

    Joined:
    Mar 17, 2010
    Messages:
    8,582
    Location:
    Doing your mom
    Country:
    Norway
    Try this instead.
    percent = i * 100 / numchucks
    That should work without requiring floats.
    Edit: :ninja:
     
    scooby74029 likes this.
  14. scooby74029
    OP

    Member scooby74029 "fake coder"

    Joined:
    May 7, 2010
    Messages:
    1,174
    Location:
    oklahoma, USA
    Country:
    United States
    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
     
  15. Supercool330

    Member Supercool330 GBAtemp Advanced Fan

    Joined:
    Sep 28, 2008
    Messages:
    659
    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).
     
    scooby74029 likes this.
  16. scooby74029
    OP

    Member scooby74029 "fake coder"

    Joined:
    May 7, 2010
    Messages:
    1,174
    Location:
    oklahoma, USA
    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.
     
  17. SifJar

    Member SifJar Not a pirate

    Joined:
    Apr 4, 2009
    Messages:
    6,022
    Country:
    United Kingdom
    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. Foxi4

    Reporter Foxi4 On the hunt...

    pip
    Joined:
    Sep 13, 2009
    Messages:
    22,736
    Location:
    Gaming Grotto
    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.
     
    scooby74029 and Psionic Roshambo like this.
  19. PsyBlade

    Member PsyBlade Snake Charmer

    Joined:
    Jul 30, 2009
    Messages:
    2,204
    Location:
    Sol III
    Country:
    Germany
    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. SifJar

    Member SifJar Not a pirate

    Joined:
    Apr 4, 2009
    Messages:
    6,022
    Country:
    United Kingdom
    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]
     

Share This Page