2009-05-08 2 views
6

Я попытаюсь объяснить эту проблему наилучшим способом я могу с кодом:увеличение, уменьшение в процентах

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 

Так что мне нужно это масштабируемое решение, которое возвращается к исходному значению, используя только количество , Есть идеи?

ответ

19

Лучший способ сделать это - использовать функцию. Он не должен выглядеть точно так, но:

class Whatever 
{ 

    private double basePower = 5000; 

    public int numPowerUps = 5; 

    public double GetActualPower() 
    { 
     return basePower + (numPowerUps * basePower * 0.1); 
    } 
} 

Просто измените numPowerUps обратно в 0, когда они закончатся. Таким образом, он выглядит очень аккуратно.


В сторону:
Причина, по которой не работает из-за того, что добавление и вычитая проценты не работает. Например:

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 

Вы всегда будете на 99% от вашего первоначального значения. Если вы действительно хотите взять ярлык, вы могли бы вместо того, чтобы сделать это:

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 

Но тогда вы потенциально подвержены плавающей ошибки точки. Функциональный способ сделать это не только более аккуратный и понятный, но и потенциально менее подверженный ошибкам.

+0

Ваш комментарий к сообщению coobird - это именно то, что я пытаюсь исправить. –

+5

@ cellis5078 - Лучший способ сделать это - вспомнить, к чему он должен вернуться, сохраняя это * и не меняя его *. И когда вы хотите увидеть, что такое «приведенное в действие» значение, выполните вычисления. Это полезно по нескольким причинам: это более аккуратно, невозможно потерять информацию о том, сколько у них бонусов (так как вы тоже это сохраняете), и у него не будет ошибок с плавающей запятой. – Smashery

+0

+1, хорошее объяснение –

1

Я буду подозревать, что вы подразумеваете под «не работает», так это то, что значение для power не должно быть точно 3750.

Это связано с floating-point rounding errors, как floating point значения, такие как double и float не могут быть представлены точные значения.

Если нужны точные значения, то использование decimal или int было бы лучшим решением, поскольку они предназначены для обработки точных значений.

Редактировать Настоящая проблема здесь не является ошибкой округления с плавающей запятой, но проблема отмечена в Smashery's answer.

+4

Нет, я думаю, проблема в том, что если вы добавите 10%, а затем вычтите 10%, вы получите 99% от вашего первоначального значения. 1 + 10% = 1,1, а затем 1,1 * 90% = 0,99 – Smashery

+1

Ах, вы правы Smashery, это, кажется, проблема здесь. – coobird

2

Это не работает, потому что два процента не берутся с одного и того же номера. Они взяты из одной и той же переменной, но не с одинаковым числом.

В первый раз power * 0.10 составляет 500 и 5 * 500 = 2500, поэтому мощность будет равна 5000 + 2500 = 7500. Теперь мощность 7500, поэтому power * 0.10 - 750. 5 * 750 = 3750 и 7500-3750 = 3750, а не 5000, как вы начали с.

Так что, по-видимому, вы не хотите, чтобы/уменьшалось на процент от текущей мощности. Возможно, было бы лучше установить базовую мощность (скажем, 5000) и фактическую мощность. Затем, когда вы в/уменьшаете, вы используете actualPower = actualPower + 5*0.1*basePower; или что-то в этом роде. Или вы просто согласны с тем, что пять отключений питания после пяти бонусов не возвращают вас к первоначальному hp.

4

Чтобы отменить увеличение% возраст, вы должны разделяй оригинальным% возраста, не вычитать.

i.e.:

100 + 5% = 100 * 1.05 = 105 

повернуть его вспять:

105/1.05 = 100 

более обычный '5% от' формула вместо даст вам:

105 - 5% = (105 * 0.95) = 99.75 
4

Для включения питания:

power <- power * (1 + count * percent); 
eg: 5000 * (1 + 5 * 0.1) 
    5000 * 1.5 
    7500 

Чтобы отключить питание:

power <- power/(1 + count * percent) 
eg: 7500/(1 + 5 * 0.1) 
    7500/1.5 
    5000 

Давайте более сложный пример, 17 бонусы, каждый из которых дает 3% к intial 1234 Мощность:

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 

Это на самом деле выглядит довольно просто, когда вы пишете это так.

Смежные вопросы