2012-05-22 9 views
15

Ich versuche, die Integral- und Bruchteile von einem Dezimalwert zu extrahieren (beide Teile sollen ganze Zahlen):Split Dezimal-Variable in Integral- und Bruchteile

decimal decimalValue = 12.34m; 
int integral = (int) decimal.Truncate(decimalValue); 
int fraction = (int) ((decimalValue - decimal.Truncate(decimalValue)) * 100); 

(für meine Zwecke, enthalten dezimal Variablen oben auf 2 Dezimalstellen)

Gibt es bessere Möglichkeiten, dies zu erreichen?

+0

Ein besserer Ansatz nicht sein kann, überhaupt eine Dezimalzahl zu verwenden, aber verwenden, um eine 'int' /' long' darstellt „Ihr Wert multipliziert mit 100“ . – Rawling

+0

Vorsicht vor ungewöhnlichen Werten. Der Maximalwert für eine Dezimalstelle ist ~ 7.9e28. Der maximale Wert für ein int ist ~ 2e9 (wesentlich kleiner). Sogar lange geht nur zu ~ 9e18. Wenn Sie also wissen, dass der Wert immer> = 0 ist, können Sie ein ulong verwenden, das bis zu ~ 18e18 reicht und etwas mehr Spielraum gibt. – Davio

+0

Folgende Antwort auf eine ähnliche Frage kann diese Bedürfnisse für Bruchteil Teil: http://StackOverflow.com/a/13038524/1178314 –

Antwort

1

Wie wäre:

int fraction = (int) ((decimalValue - integral) * 100); 
+0

Es wird sicher nicht für negative Zahlen arbeiten. – SOReader

+1

Was ist "integral"? –

-1

wie etwa die toString-Funktion und dann auf dem Komma geteilt, das heißt:

[Bearbeiten] schnelle kleine Klasse/Methode zu testen:

public class Test 
{ 
    public struct FractionSplit 
    { 
     public int BeforeDecimal; 
     public int AfterDecimal; 
    } 

    public FractionSplit SplitDecimal(decimal decimalValue, 
             int decimalPrecision = 2) 
    { 
     // now do the split - the apres decimal precision defined by 
     // the format function which defaults to 2 places i.e. "0.00" 
     string splitValue = decimalValue.ToString(string.Format("0.{0}", 
      new String('0', decimalPrecision)), CultureInfo.InvariantCulture); 
     string[] splitParts = splitValue.Split('.'); 

     // now factor out derived splits as ints into struct 
     var fractionSplit = new FractionSplit 
     { 
      BeforeDecimal = int.Parse(splitParts[0]), 
      AfterDecimal = int.Parse(splitParts[1]) 
     }; 

     return fractionSplit; 
    } 
} 

useage:

Test test = new Test(); 
var result = test.SplitDecimal(12.1m); 

Gemäß Dans Kommentar wird dies in der Tat folgern, dass 12.1 12 und 10 als resultierende Ganzzahlen zurückgibt. Ist es richtig?? - wer weiß, aber deckt diesen Anwendungsfall vorerst ab. Dies liegt an dem ToString-Teil ("0. {0}"), der standardmäßig eine '0' am Ende einer Dezimalstelle hinzufügt, die nur eine Ziffer hat.

+0

ergibt 0,1 das gleiche Ergebnis wie 0,10 oder 0,01 obwohl? – Dan

+0

ashh - guter Punkt !! prolly nicht, tho, ist nicht 10 und 1 das gewünschte Ergebnis ?? :) d. h. 12,10 würde 12 und 10 ergeben, 12,01 würde 12 und 1 ergeben. Ist das nicht korrekt? –

+0

ja aber was dann würde 12.1 geben? Möglicherweise 1, wenn das gewünschte Ergebnis 10 sein könnte ... Ich bin mir nicht sicher – Dan

2

Versuchen mathematische Definition:

var fraction = (int)(100.0m * (decimalValue - Math.Floor(decimalValue))); 

Obwohl es nicht besser in der Leistung Sinne, aber es zumindest Arbeit für negative Zahlen.

+0

Versuchen Sie folgendes zu verwenden: var FileMinorPartClient = (int) (100.0m * (clientFileVersion - Math .Floor (clientFileVersion))); Ich bekomme: "Operator '*' kann nicht auf Operanden vom Typ 'Dezimal' und 'Doppel'" (clientFileVersion ist ein Doppel, a la 1.4) –

+1

@ B.ClayShannon Es sagt, weil Sie diese beiden nicht mischen können . Entweder "100.0m" in "100.0" ändern oder sicherstellen, dass "decimalValue" vom "Dezimal" -Typ ist – SOReader

7
 decimal fraction = (decimal)2.78; 
     int iPart = (int)fraction; 
     decimal dPart = fraction % 1.0m; 
+0

Sehr gute Verwendung des Modulo-Operators für Dezimalzahlen. Ich habe nicht erwartet, dass das funktioniert, aber es ist schön (und es ist schnell) :) –

3
decimal fraction = doubleNumber - Math.Floor(doubleNumber) 

oder so ähnlich.

1

Für Fraktion herausnehmen können Sie this solution verwenden:

Math.ceil(((f < 1.0) ? f : (f % Math.floor(f))) * 10000)