2016-09-08 6 views
0

Dieser Teil des Code sollte für sich selbst sprechen, meine Frage ist, kann ich 1242,08 Ergebnis in res Variable zu erhalten, und nicht 1242,07, weil in MatheAbrunden von dezimal in C# scheinen falsch

b = 1/(1/b) 

und in Doppel die weniger Präzision es scheint, dass ich gutes Ergebnis

Kann ich Dezimalteil Berechnungs beheben, um mir mathematisch richtige Ergebnis bekam:

decimal rate = 124.2075M; 
decimal amount = 10M; 
decimal control = decimal.Round(rate * amount, 2); //it is 1242.08 

//but 
decimal res = decimal.Round(amount * (1/(1/rate)), 2);//1242.07 - should be 1242.08 
decimal res1 = decimal.Round(amount * 124.2075M, 2);//1242.08 OK 

///////////////////////////////////////////////////////////// 

//while with double seems OK 
double ratef = 124.2075; 
double amountf = 10; 
double resf = Math.Round(amountf * (1/(1/ratef)), 2);//1242.08 OK 
double res1f = Math.Round(amountf * 124.2075, 2);//1242.08 OK 
+0

Sie können Math.Round (1242.075M * 100)/100 versuchen. –

+0

Die Identität 'b = 1/(1/b)', die in reiner Mathematik gut ist (für nicht-null 'b'), gilt einfach nicht für die Fließkomma-Arithmetik. Insbesondere, wenn "rate" "124.2075M" ist, dann ist "1M/(1M/rate)" etwas anderes, nämlich "124.20749999999999999999999991M". Das Gute an "Dezimal" ist, dass Sie aus der gedruckten Darstellung des Wertes deutlich sehen können, dass es nicht das Gleiche ist. (Für 'double' und' float' gibt es manchmal eine "versteckte" Genauigkeit, es sei denn, Sie verwenden eine spezielle Formatzeichenkette zum Ausdrucken des Wertes.) –

+0

Tun Sie dies selbst mit einem Stück Papier und verwenden Sie eine lange Division, um 1/124.2075 zu berechnen Du hast in der Grundschule gelernt. Das Papier ist nicht groß genug, um die unendliche Folge von Ziffern im Ergebnis zu schreiben, man muss irgendwo anhalten. Und wenn Sie es erneut mit dem abgeschnittenen Ergebnis tun, das Sie aufgeschrieben haben, erhalten Sie natürlich nicht den ursprünglichen Wert zurück. Computer funktionieren nicht anders, sie haben auch keinen unbegrenzten Speicher. Ihre Annahme, dass dies möglich sein sollte, ist einfach nicht richtig. –

Antwort

4

das ist eine Beschränkung des Datentyps ist decimal, die bis zu 29 digits

halten kann Das Ergebnis der ersten Berechnung (res1) passt nicht in Dezimal, damit Sie ein ungültiges/ungenaues Ergebnis erhalten.

decimal rate = 124.2075M; 
decimal amount = 10M; 

decimal res1 = (1/rate); //0.0080510436165287925447336111M <- not enough decimal places 
decimal res2 = (1/res1); //124.20749999999999999999999991M 
decimal res3 = amount * res2; //1242.0749999999999999999999991M 
decimal res4 = decimal.Round(res3, 2); //1242.07M <- correct rounding 
+0

Ich habe festgestellt, dass wenn ich Runde 1/Rate auf etwa 10 Ziffern Ich habe 1242.08, ist das zufällig? Oder kann ich etwas so verwenden, um das zu beheben? – vldmrrdjcc

+1

Das ist zufällig, weil Sie alles nach '0.0080510436' abgeschnitten haben. Aber das ist keine allgemeine Lösung für alle Zahlen - das funktioniert einfach nur für diesen – fubo

+0

Sollte ich für diese Berechnung einen anderen Datentyp verwenden, sah ich, dass bei Double das richtige Ergebnis kommt, ist es auch zufällig, dass Double zu funktionieren scheint? – vldmrrdjcc