Need Math Help

Jeckel

Great Reverend
Joined
Nov 16, 2005
Messages
1,637
Location
Peoria, IL
Ok guys, math is not my strong suit. I can generally take an algorithm and cut/paste it to where I need, or wrap code I understand around it, but ask me to figure out how (or worse why) the math works and I'm not going to give you anything.

What I got is pretty simple on the math side. I have a function that takes two number arguments and returns what percentage the first arg (oValue) is of the second arg (oWhole).

Code:
template <typename T>
T percent(T oValue, T oWhole)
{
	return (oValue * oWhole) / T(100);
}

If you don't know templates, then ignore the 'template <typename T>' line and replace the 'T' with 'int'.

The math is real simple. I don't recall where I got the code, might have been Civ4, but it has worked fine for everything I have thrown at it so far.

The following is some test output showing the result of various values.

Code:
percent(1, 100): 1
percent(50, 100): 50
percent(100, 100): 100

percent(-1, 100): -1
percent(-50, 100): -50
percent(-100, 100): -100

percent(1, -100): -1
percent(50, -100): -50
percent(100, -100): -100

percent(-1, -100): 1
percent(-50, -100): 50
percent(-100, -100): 100

I think those are all the right outputs, someone correct me if it isn't and that can be addressed also... heck, if it is right, would be nice if some one could give me that confirmation.. ;)


The problem I am having is when I use double (float) values, the output is not what I desire.

Code:
percent(0.01, 1.00): 0.0001
percent(0.50, 1.00): 0.0050
percent(1.00, 1.00): 0.0100

I know why it gives this output, 0.01 * 1 = 0.01 and then 0.01 / 100 = 0.0001, but I couldn't explain why a number times a number divided by a hundred would ever give the desired percentage, much less what conditions I should check for to stop it from giving the improper output when it does.

I'm sure the answer is simple, but if this was a question on Are You Smarter Then A Fifth Grader, I would have to drop out of school. Some help would be appreciated. :)
 
The correct function for calculating how much percent A is from B is:

F(A,B) = A/B*100

The 100 is there to make the 'per one' to 'per cent', that's all there is to is really. Don't know why you have to divide by 100 there. :dunno:

Also, for more information: http://en.wikipedia.org/wiki/Percent
 
Well there you go. I'm sure I'll spend hours staring at that little line, trying to break it down into the pseudo-assembly code in my head, but regardless if I understand it, it worked in all my test cases. Thank you much. :king:

I've looked at that wikipedia page several times, but.. I understand why some people's eyes glaze over when they look at computer code or a car engine or a recipe... cause that is what happens to me about two sentences into any math more complex then 2 + 2. :p


But again, thank you. I never would have figured that out on my own, you rock. :band:
 
The funny thing is that your original function was working for ints because the oWhole value was always 100 or -100, so it was interchangeable with the T(100) in your function! This is where a good test suite of varied values comes in handy.

BTW, for ints it is best to multiply by 100 first before dividing by the whole value. This will minimize the loss from integer division.

Code:
template <typename T>
T percent(T oValue, T oWhole)
{
	return oValue * T(100) / oWhole;
}
 
The funny thing is that your original function was working for ints because the oWhole value was always 100 or -100, so it was interchangeable with the T(100) in your function! This is where a good test suite of varied values comes in handy.

Ahh, that explains why it did work in those cases, and I can wrap my head around that, I was multiplying and then dividing by 100, so they basically canceled each other out.

Yea, your right about testing being handy, that is the part I am writing now and was how I found this problem. I started with the simple 100 tests first cause I knew what the output should be, and knew it would show if my math was flat out incorrect in the simplest cases. Today I will now move on to extending the test cases and then start testing on the next function.

BTW, for ints it is best to multiply by 100 first before dividing by the whole value. This will minimize the loss from integer division.

Ok, I can see that, I'll update the function accordingly, thanx. :goodjob:
 
Top Bottom