Увеличение, уменьшение в процентах - PullRequest
6 голосов
/ 08 мая 2009

Я постараюсь объяснить эту проблему наилучшим образом с помощью кода:

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

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

Ответы [ 5 ]

19 голосов
/ 08 мая 2009

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

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

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

4 голосов
/ 08 мая 2009

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

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 бонусов, каждый из которых дает начальную мощность 1234 по 3%:

  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

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

4 голосов
/ 08 мая 2009

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

т.е:.

100 + 5% = 100 * 1.05 = 105

чтобы изменить это:

105 / 1.05 = 100

Более обычная формула «5% скидка» вместо этого даст вам:

105 - 5% = (105 * 0.95) = 99.75
2 голосов
/ 08 мая 2009

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

В первый раз 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; или что-то. Или вы просто соглашаетесь с тем, что пять понижений мощности после пяти повышений не возвращают вас к исходному уровню здоровья.

1 голос
/ 08 мая 2009

Я собираюсь заподозрить, что вы подразумеваете под "не работает" то, что значение для power не в конечном итоге будет точно 3750.

Это связано с ошибками округления с плавающей запятой , поскольку значения с плавающей запятой , такие как double и float, не могут быть представлены точными значениями.

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...