6 votes

Incrémenter, décrémenter en pourcentage

Je vais essayer d'expliquer ce problème du mieux que je peux avec du 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

J'ai donc besoin d'une solution évolutive qui me ramène à la valeur d'origine en utilisant uniquement le comptage. Des idées ?

19voto

Smashery Points 13208

La meilleure façon de le faire est d'utiliser une fonction. Elle n'a pas besoin de ressembler exactement à ça, mais.. :

class Whatever
{

    private double basePower = 5000;

    public int numPowerUps = 5;

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

Il suffit de remettre numPowerUps à 0 lorsqu'ils sont épuisés. De cette façon, c'est beaucoup plus clair.

Une parenthèse :
La raison pour laquelle cela ne fonctionne pas est que l'addition puis la soustraction de pourcentages ne fonctionne pas. Par exemple :

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

Vous vous retrouverez toujours avec 99% de votre valeur initiale. Si vous voulez vraiment prendre un raccourci, vous pouvez faire ceci :

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

Mais vous êtes alors potentiellement susceptible de commettre des erreurs de virgule flottante. La méthode de la fonction est non seulement plus claire et plus nette, mais aussi potentiellement moins sujette aux erreurs.

4voto

Alnitak Points 143355

Pour annuler une augmentation en pourcentage, vous devez diviser par le %age original, et non soustraire .

c'est-à-dire :

100 + 5% = 100 * 1.05 = 105

pour l'inverser :

105 / 1.05 = 100

La formule plus habituelle "5% de réduction" vous donnerait plutôt.. :

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

4voto

paxdiablo Points 341644

Pour mettre sous tension :

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

Pour redescendre en puissance :

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

Prenons un exemple plus compliqué : 17 bonus, chacun donnant 3 % d'un pouvoir initial de 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

Ça a l'air assez simple quand on l'écrit comme ça.

2voto

Jordi Points 2120

Cela ne fonctionne pas car les deux pourcentages ne sont pas tirés du même nombre. Ils sont tirés de la même variable, mais pas du même nombre.

La première fois, power * 0.10 est de 500, et 5*500=2500 donc la puissance sera de 5000+2500=7500. Maintenant, la puissance est de 7500, donc power * 0.10 est de 750. 5*750 = 3750 et 7500-3750=3750 et non 5000 comme vous avez commencé.

Donc apparemment, ce que vous voulez n'est pas vraiment d'augmenter/diminuer d'un pourcentage de la puissance actuelle. Peut-être serait-il préférable de définir une puissance de base (disons 5000) et une puissance réelle. Ensuite, lorsque vous augmentez ou diminuez la puissance, vous utilisez la fonction actualPower = actualPower + 5*0.1*basePower; ou quelque chose comme ça. Ou vous acceptez simplement que cinq power downs après cinq power ups ne vous ramènent pas à la puissance initiale.

1voto

coobird Points 70356

Je vais soupçonner que ce que vous voulez dire par "ne fonctionne pas" est que la valeur pour power ne finit pas par être exactement 3750 .

Ceci est dû à erreurs d'arrondi en virgule flottante comme virgule flottante des valeurs telles que double y float ne sont pas en mesure de représenter des valeurs exactes.

Si des valeurs exactes sont nécessaires, il faut utiliser decimal o int serait une meilleure solution, car ils sont conçus pour traiter des valeurs exactes.

Editar Le problème réel ici n'est pas une erreur d'arrondi en virgule flottante, mais un problème noté dans La réponse de Smashery .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X