Domanda

ticketPriceInPence = 7360
percentageToRefund = 100

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

Ciò si traduce in: 73.59

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

Ciò si traduce in: 73.60

Qualche idea sul perché si traduca in 2 risultati diversi

È stato utile?

Soluzione

È il vecchio caso di numeri in virgola mobile che non sono in grado a rappresentano esattamente i decimali .

Sembra che tu abbia a che fare con i soldi qui e quindi dovresti davvero considerare l'utilizzo di decimale .

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));

Altri suggerimenti

La semplice risposta è che è dovuto all'errore di arrotondamento nelle equazioni che usano numeri in virgola mobile. Questo perché, in generale, non esiste una rappresentazione binaria esatta di un numero in virgola mobile, quindi tutto ciò che hai sono approssimazioni.

Ho notato che hai:

(percentageToRefund * 0.01)

nella prima equazione e:

(percentageToRefund * 0.01) * 100

nel secondo.

Quest'ultima espressione provocherà un errore di arrotondamento poiché prima dividi per 100, quindi moltiplichi di nuovo per 100. L'input non sarà uguale all'output, la differenza dipende dall'architettura della macchina, dal sistema operativo, dalla lingua e dal compilatore.

Se hai a che fare con denaro dovresti usare il tipo decimale (supponendo C #)

Perché un float non è un numero esatto. Consiglio di leggere http://en.wikipedia.org/wiki/Floating_point . Vedrai perché il risultato è diverso.

Per farla breve. È a causa di errori di precisione quando si rappresentano valori float come dati binari. Ciò significa fondamentalmente che non puoi rappresentare ogni possibile float con 32/64 bit, quindi 2.1 in realtà è 2.1000000000000001 ecc. Questo è uno dei motivi per cui non dovresti mai fare qualcosa come 2.145 == "altro valore che dovrebbe essere 2.145".

Suggerisco di leggere l'articolo su wikipedia per informazioni più dettagliate: Wiki Link

Ciò è dovuto alla precisione finita dei numeri in virgola mobile.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top