2009-05-08 14 views
6

voy a tratar de explicar este problema de la mejor manera que puedo con código:incrementar, decrementar en función del porcentaje

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 

Así que lo que necesito es una solución escalable que se pone de nuevo al valor original utilizando sólo el recuento . ¿Algunas ideas?

Respuesta

19

La mejor manera de hacerlo es mediante el uso de una función. No tiene que mirar exactamente como esta, pero:

class Whatever 
{ 

    private double basePower = 5000; 

    public int numPowerUps = 5; 

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

Sólo cambia numPowerUps de nuevo a 0 cuando se les acaba. De esta manera, se ve mucho más ordenado.


Un aparte:
La razón por la que no funciona es debido al hecho de que la adición y luego restar porcentajes no funciona. Por ejemplo:

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 

Siempre obtendrá el 99% de su valor original. Si realmente quiere tomar un atajo, en su lugar podría hacer esto:

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 

Pero entonces está potencialmente susceptibles a los errores de coma flotante. La forma de hacerlo funcionar no solo es más nítida y clara, sino potencialmente menos propensa a errores.

+0

Su comentario a la publicación de coobird es exactamente el problema que trato de remediar. –

+5

@ cellis5078 - La mejor manera de hacerlo es recordando a qué debe regresar almacenando * y no cambiándolo *. Y cuando desee ver cuál es el valor de "encendido", haga el cálculo a continuación. Eso es bueno por varias razones: es más nítido, es imposible perder la cuenta de cuántos power-ups tienen (ya que también lo estás almacenando), y no va a tener errores de coma flotante. – Smashery

+0

+1, buena explicación –

1

Sospecho que lo que quiere decir con "no funciona" es que el valor de power no termina siendo exactamente 3750.

Esto es debido a floating-point rounding errors, como floating point valores como double y float no son capaces de ser representados valores exactos.

Si los valores exactos son necesarios, entonces usar decimal o int sería una solución mejor, ya que están diseñados para manejar valores exactos.

Editar El problema real aquí no es un error de redondeo de coma flotante, sino un problema observado en Smashery's answer.

+4

No, creo que el problema aquí es que si agrega un 10% y luego resta un 10%, obtiene el 99% de su valor original. 1 + 10% = 1.1 y luego 1.1 * 90% = 0.99 – Smashery

+1

Ah, tienes razón Smashery, ese parece ser el problema aquí. – coobird

2

Esto no funciona porque los dos porcentajes no están tomados del mismo número. Se toman de la misma variable, pero no del mismo número.

La primera vez, power * 0.10 es 500 y 5 * 500 = 2500, por lo que la potencia será 5000 + 2500 = 7500. Ahora, la potencia es 7500, por lo que power * 0.10 es 750. 5 * 750 = 3750 y 7500-3750 = 3750 y no 5000 como comenzó.

Aparentemente, lo que desea no es realmente reducir/disminuir en un porcentaje de la potencia actual. Tal vez sería mejor establecer una potencia base (digamos 5000) y una potencia real. Luego, cuando ingresa/disminuye, usa actualPower = actualPower + 5*0.1*basePower; o algo así. O simplemente acepta que cinco apagones después de cinco power-ups no le devuelvan al HP inicial.

4

Para invertir un aumento de la edad%, se debe dividir por el original de la edad%, no reste .

i.e.:

100 + 5% = 100 * 1.05 = 105 

revertirla:

105/1.05 = 100 

El más habitual '5% de descuento' fórmula en lugar le daría:

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

Para encender:

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

Para retroceder:

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

Tomemos un ejemplo más complicado, 17 ciclos iniciales, cada uno dando un 3% a un 1,234 poder intial:

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 

En realidad se ve bastante simple cuando usted lo escribe de esa manera.

Cuestiones relacionadas