2009-05-08 15 views
6

cercherò di spiegare questo problema il modo migliore che posso con il codice:incremento, decremento in percentuale

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 

Così che cosa ho bisogno è una soluzione scalabile che torna al valore originale utilizzando solo il conteggio . Qualche idea?

risposta

19

Il modo migliore per farlo è utilizzare una funzione. Essa non deve apparire esattamente come questo, ma:

class Whatever 
{ 

    private double basePower = 5000; 

    public int numPowerUps = 5; 

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

Basta cambiare numPowerUps di nuovo a 0 quando si esauriscono. In questo modo, sembra molto più ordinato.


Una parentesi:
La ragione non sta funzionando è a causa del fatto che l'aggiunta e quindi le percentuali sottraendo non funziona. Per esempio:

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 

Avrai sempre finisce con il 99% del valore originario. Se davvero si vuole prendere una scorciatoia, si potrebbe invece fare questo:

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 

Ma allora siete potenzialmente suscettibile di floating point errori. Il modo di farlo è non solo più ordinato e chiaro, ma potenzialmente meno soggetto a errori.

+0

Il tuo commento al post di coobird è esattamente il problema che sto cercando di porre rimedio. –

+5

@ cellis5078 - Il modo migliore per farlo è ricordarsi di cosa dovrebbe tornare memorizzando quello * e non cambiandolo *. E quando vuoi vedere qual è il valore "potenziato", fai il calcolo allora. Ciò è positivo per diversi motivi: è più ordinato, è impossibile perdere traccia di quanti power-up hanno (visto che lo stai memorizzando), e non avrà errori in virgola mobile. – Smashery

+0

+1, buona spiegazione –

1

Sospetto che ciò che intendi per "non funziona" è che il valore per power non termina esattamente con 3750.

Ciò è dovuto al floating-point rounding errors, come floating point valori come double e float non possono essere rappresentati valori esatti.

Se sono necessari valori esatti, utilizzare decimal o int sarebbe una soluzione migliore, poiché sono progettati per gestire valori esatti.

Modifica Il problema reale qui non è un virgola mobile errore di arrotondamento, ma un problema notato in Smashery's answer.

+4

No, penso che il problema qui sia che se si aggiunge il 10% e quindi si sottragge il 10%, si ottiene il 99% del valore originale. 1 + 10% = 1.1 e poi 1.1 * 90% = 0.99 – Smashery

+1

Ah, hai ragione Smashery, questo sembra essere il problema qui. – coobird

2

Questo non funziona perché le due percentuali non sono prese dallo stesso numero. Sono presi dalla stessa variabile, ma non lo stesso numero.

La prima volta, power * 0.10 è 500 e 5 * 500 = 2500 quindi la potenza sarà 5000 + 2500 = 7500. Ora, la potenza è 7500, quindi power * 0.10 è 750. 5 * 750 = 3750 e 7500-3750 = 3750 e non 5000 come hai iniziato.

Quindi, a quanto pare, ciò che si desidera non è in realtà in/diminuire di una percentuale della potenza corrente. Forse sarebbe meglio impostare una potenza di base (diciamo 5000) e una potenza effettiva. Quindi quando entri/decidi, usi actualPower = actualPower + 5*0.1*basePower; o qualcosa del genere. O accetti solo che cinque power down dopo cinque power up non ti riportano alla versione iniziale di hp.

4

Per invertire un aumento% di età, è necessario dividere dall'età originale%, non sottrarre.

, ad es.:

100 + 5% = 100 * 1.05 = 105 

per invertire tale tendenza:

105/1.05 = 100 

Il più usuale '5% di sconto' formula sarebbe invece dare:

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

Per accendere:

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

Per riaccendere:

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

Facciamo un esempio più complesso, 17 power up, ciascuna dando 3% a un 1234 di potenza 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 

In realtà sembra piuttosto semplice quando si scrive in quel modo.

Problemi correlati