[RESOLVED] Need a sanity check - calculating percentages in a loop
First up, the code:
vb.net Code:
If ((rowCount / totalRows) * 100) Mod 10 = 0 Then
Now for the explanation:
I've got a loop where I'm processing a file line by line. Through the process, I want to give some feed back to the user. I want to do it on each 10% (10,20,30, etc)
totalRows is the number of rows in the file. rowCount is the current row I'm about to process.
Obviously rowCount/totalRows gives back the decimal value, which I then multiple by 100 get the percent value. I then mod it by 10 and see if it is 0, and if it is, I update the user with a message.
Seems straight forward, right? Problem is I'm getting 20%, 40%, 60%, 80%, and 100%, I'm missing 10, 30, 50, 70 & 90...
I think it might be because I don't get an exact 10%... it might be doing something like 9.98, followed by 11.1 ... so it skips 10%
I've tried putting a cint around the left portion before the modulus operation... that didn't work, I've tried flipping the / for \ that didn't help...
What am I missing?
-tg
pre-posting edit - ok, I confirmed that the problem is that I'm not hitting perfect % on the odd ones... if I hard code totalRows to 100, then I get 10, 20, 30,... as expected... so ... hmmm.... now I don't know what to do. Is there a way to do a "slop" range?
Re: Need a sanity check - calculating percentages in a loop
Well, that math will result in you Moding against a Double. I've never tried that, but it shouldn't work perfectly in all cases due to that funny precision thing with doubles. How about just tossing a CInt() into the mix so that you are Moding against an Integer.
Overlooked the point where you HAD a CInt. It should work, but I never remember what CInt does. Does it just chop off the decimal, or does it round it? If it just truncates, then it won't work, but some rounding should do it.
Re: Need a sanity check - calculating percentages in a loop
How about divide totalRows by 10, round that and then do a Mod with that value? Won't be exact but you wanted slop. :p
E.g., If totalRows = 15743 then
Code:
If rowCount Mod 1574 = 0 Then
Re: Need a sanity check - calculating percentages in a loop
Hi ,
even if you are counting rows for calc I think you still must use 'Math.Round'
Code:
Dim wonGames As Double
Dim allGames As Double
wongames = 22
allgames = 222
MsgBox(Math.Round(wongames * 100 / allgames, 2).ToString & "%")
regards
chris
Re: Need a sanity check - calculating percentages in a loop
Quote:
Originally Posted by
Shaggy Hiker
Well, that math will result in you Moding against a Double. I've never tried that, but it shouldn't work perfectly in all cases due to that funny precision thing with doubles. How about just tossing a CInt() into the mix so that you are Moding against an Integer.
Overlooked the point where you HAD a CInt. It should work, but I never remember what CInt does. Does it just chop off the decimal, or does it round it? If it just truncates, then it won't work, but some rounding should do it.
Yeah, I'm not sure what was going on inside, but the CInt gave me incremental percentage as well as the whole ones...
Quote:
Originally Posted by
topshot
How about divide totalRows by 10, round that and then do a Mod with that value? Won't be exact but you wanted slop. :p
E.g., If totalRows = 15743 then
Code:
If rowCount Mod 1574 = 0 Then
That's not half bad (in fact it might even be 78.95% good... I ended up mucking with totalRows and rounding it up to the next 10.
Code:
' round up to the next 10 (not nearest 10, next 10)
totalRows += 10 - (totalRows Mod 10)
So now all the percentages seem to end up on the correct marks
Quote:
Originally Posted by
ChrisE
Hi ,
even if you are counting rows for calc I think you still must use 'Math.Round'
Code:
Dim wonGames As Double
Dim allGames As Double
wongames = 22
allgames = 222
MsgBox(Math.Round(wongames * 100 / allgames, 2).ToString & "%")
regards
chris
Now I feel like a dolt... Math.Round probably would have solved the issue from the get-go. Thanks. I might give that a try and see if it works.
-tg
Re: Need a sanity check - calculating percentages in a loop
Hi ,
another way could be to compensate the 0,01 with adding
somthing like 0.5
Code:
Public Function Percent(ByVal CurrVal As Long, ByVal MaxVal As Long) As Integer
Return Int(CurrVal / MaxVal * 100 + 0.5)
End Function
regards
chris
Re: Need a sanity check - calculating percentages in a loop
Here's what I ended up using..
Code:
If (Math.Round(((rowCount / totalRows) * 100))) Mod 10 = 0 Then 'Every 10% completion
It has an interesting side effect that adds (in a positive way) to the experience.
-tg
Re: Need a sanity check - calculating percentages in a loop
Quote:
Originally Posted by
techgnome
Here's what I ended up using..
Code:
If (Math.Round(((rowCount / totalRows) * 100))) Mod 10 = 0 Then 'Every 10% completion
It has an interesting side effect that adds (in a positive way) to the experience.
-tg
Oh come on. Don't be leaving us hanging.
Re: Need a sanity check - calculating percentages in a loop
Quote:
Originally Posted by
Shaggy Hiker
How about just tossing a CInt() into the mix so that you are Moding against an Integer.
rowCount and totalRows are both integers surley... Whatever maths you perform on integers will always 'round down' to a whole integer anyway.
Poppa.
Re: Need a sanity check - calculating percentages in a loop
Those two may be integers, but when you use / for division, you get a double or a decimal, and you only get the decimal if the numerator and denominator are both decimals.
(and I'm having a really hard time not saying, "and don't call me Shirley, but I'm not sure whether you'd get the reference).
Re: Need a sanity check - calculating percentages in a loop
Quote:
Originally Posted by
Shaggy Hiker
(and I'm having a really hard time not saying, "and don't call me Shirley, but I'm not sure whether you'd get the reference).
I may be ancient, but surly that means I go back far enough to 'Get' the reference.
Poppa.
Re: Need a sanity check - calculating percentages in a loop
I don't know what the surrounding code looks like, but I'm kind of old school from the days when doing divides were pretty expensive so try to avoid using / and Mod (which does an Integer divide) in a loop when possible.
I tend to compute a trigger value, compare against that and increment it when triggered. Of course if your totalRows value is changing during the loop, then that would invalidate the simple case. These days, it probably doesn't make that much difference, but it is a habit for me.
Code:
Dim PercentComplete As Integer
Dim TriggerIncrement As Double = totalRows / 10 'inform the user every 10%
Dim TriggerValue As Double = TriggerIncrement 'initial trigger (at 10%)
'Start your loop and in the loop
If rowcount > TriggerValue Then
PercentComplete += 10
TriggerValue += TriggerIncrement
'inform user of PercentComplete
End If
'process etc
Re: Need a sanity check - calculating percentages in a loop
Quote:
Originally Posted by
Poppa Mintin
I may be ancient, but surly that means I go back far enough to 'Get' the reference.
Poppa.
Oh, I knew you were old enough. I just wasn't sure whether that movie got as much play across the pond as it did in the US.
Re: Need a sanity check - calculating percentages in a loop
Quote:
Originally Posted by
Shaggy Hiker
Oh come on. Don't be leaving us hanging.
It's a visual thing... but it causes the counter and the pct notification to spin in spurts... so it shows some action rather than just chunking. It speeds up, then pauses for a moment, speeds up again, pauses to catch its breath...
-tg