Reputation: 3881
I'll try to explain this problem the best way i can with code:
double power = 5000;
//picked up 5 power ups, now need to increase power by 10% per powerup
power += 5 * (power * .10);
//later on...ran into 5 power downs need to decrease power back to initial hp
power -= 5 * (power * .10);//7500 - 3750 -- doesn't work
So what i need is a scaleable solution that gets back to the original value using only the count. Any ideas?
Upvotes: 6
Views: 14192
Reputation: 59673
The best way to do this is using a function. It doesn't have to look exactly like this, but:
class Whatever
{
private double basePower = 5000;
public int numPowerUps = 5;
public double GetActualPower()
{
return basePower + (numPowerUps * basePower * 0.1);
}
}
Just change numPowerUps back to 0 when they run out. This way, it looks a whole lot neater.
An aside:
The reason it's not working is because of the fact that adding and then subtracting percentages doesn't work. For instance:
1. What is 10% of 100? --> 10
2. Add that to the 100 --> 110
3. What is 10% of 110? --> 11
4. Subtract that from 110 --> 99
You'll always end up with 99% of your original value. If you really want to take a shortcut, you could instead do this:
1. What is 10% of 100? --> 10
2. Add that to the 100 --> 110
3. What is (100/11) = 9.09090909...% of 110? --> 10
4. Subtract that from 110 --> 100
But then you're potentially susceptible to floating point errors. The function way of doing it is not only neater and clearer, but potentially less error-prone.
Upvotes: 19
Reputation: 882028
To power up:
power <- power * (1 + count * percent);
eg: 5000 * (1 + 5 * 0.1)
5000 * 1.5
7500
To power back down:
power <- power / (1 + count * percent)
eg: 7500 / (1 + 5 * 0.1)
7500 / 1.5
5000
Let's take a more complicated example, 17 power ups, each giving 3% to an intial 1234 power:
1234 * (1 + 17 * 0.3)
= 1234 * (1 + 5.1)
= 1234 * 6.1
= 7527.4
7527.4 / (1 + 17 * 0.3)
= 7527.4 / (1 + 5.1)
= 7527.4 / 6.1
= 1234
It actually looks pretty simple when you write it out like that.
Upvotes: 4
Reputation: 339917
To reverse a %age increase, you must divide by the original %age, not subtract.
i.e.:
100 + 5% = 100 * 1.05 = 105
to reverse it:
105 / 1.05 = 100
The more usual '5% off' formula would instead give you:
105 - 5% = (105 * 0.95) = 99.75
Upvotes: 4
Reputation: 160992
I'm going to suspect that what you mean by "doesn't work" is that the value for power
does not end up to be exactly 3750
.
This is due to floating-point rounding errors, as floating point values such as double
and float
are not able to be represented exact values.
If exact values are needed, then using decimal
or int
would be a better solution, as they are designed to handle exact values.
Edit The actual issue here is not a floating-point rounding error, but an issue noted in Smashery's answer.
Upvotes: 1
Reputation: 5908
This doesn't work because the two percentages are not taken from the same number. They're taken from the same variable, but not the same number.
The first time, power * 0.10
is 500, and 5*500=2500 so the power will be 5000+2500=7500. Now, the power is 7500, so power * 0.10
is 750. 5*750 = 3750 and 7500-3750=3750 and not 5000 like you started out with.
So apparently, what you want is not really to in/decrease by a percentage of the current power. Perhaps it would be better to set a base power (let's say 5000) and an actual power. Then when you in/decrease, you use actualPower = actualPower + 5*0.1*basePower;
or something. Or you just accept that five power downs after five power ups does not get you back to initial hp.
Upvotes: 2