2009-10-22 11 views
0
ticketPriceInPence = 7360 
percentageToRefund = 100 

(int)(Math.Round((ticketPriceInPence * 0.01) * (percentageToRefund * 0.01), 2, MidpointRounding.AwayFromZero) * 100) 

Il en résulte: 73,59résultat différent dans Math.Round

(int)(Math.Round((ticketPriceInPence * 0.01) * (percentageToRefund * 0.01) * 100, 2, MidpointRounding.AwayFromZero)) 

Il en résulte: 73,60

Toute idée pourquoi il se traduit par différents 2 résultats différents

+0

Veuillez indiquer la langue utilisée et le type de variables. –

Répondre

4

C'est le old case des nombres à virgule flottante ne pouvant pas represent decimals exactly.

Vous semblez avoir affaire à de l'argent ici et alors vous devriez vraiment envisager d'utiliser decimal.

decimal ticketPriceInPence = 7360; 
decimal percentageToRefund = 100; 
var result1 = (int)(Math.Round((ticketPriceInPence * 0.01m) * (percentageToRefund * 0.01m), 2, MidpointRounding.AwayFromZero) * 100); 
var result2 = (int)(Math.Round((ticketPriceInPence * 0.01m) * (percentageToRefund * 0.01m) * 100, 2, MidpointRounding.AwayFromZero)); 
0

Longue histoire courte. C'est à cause des erreurs de précision lors de la représentation des valeurs flottantes en tant que données binaires. Cela signifie que vous ne pouvez pas représenter tous les flottants possibles avec 32/64 bits, donc 2.1 en réalité est 2.1000000000000001 etc. C'est une raison pour laquelle vous ne devriez jamais faire quelque chose comme 2.145 == "autre valeur qui devrait être 2.145".

Je vous suggère de lire l'article à wikipedia pour plus d'informations: Wiki Link

1

La réponse simple est que ce soit en raison de l'arrondissement des chiffres dans les équations à l'aide de nombres à virgule flottante. C'est parce que, en général, il n'y a pas de représentation binaire exacte d'un nombre à virgule flottante donc tout ce que vous avez est des approximations.

Je remarque que vous avez:

(percentageToRefund * 0.01) 

dans la première équation, et:

(percentageToRefund * 0.01) * 100 

dans le second. Cette dernière expression entraînera une erreur d'arrondi lorsque vous divisez d'abord par 100, puis multipliez par 100 à nouveau. L'entrée ne sera pas égale à la sortie, la différence dépend de l'architecture de la machine, du système d'exploitation, de la langue et du compilateur.

Si vous avez affaire avec de l'argent, vous devez utiliser le type decimal (en supposant C#)

0

Ceci est dû à la précision finie de nombres à virgule flottante.