Frage

Diese Zeilen in C#

decimal a = 2m;
decimal b = 2.0m;
decimal c = 2.00000000m;
decimal d = 2.000000000000000000000000000m;

Console.WriteLine(a);
Console.WriteLine(b);
Console.WriteLine(c);
Console.WriteLine(d);

Generiert diese Ausgabe:

2
2.0
2.00000000
2.000000000000000000000000000

Ich kann also sehen, dass es mir die Präzision kontrollieren kann, dass ich eine Dezimalvariable aus einem wörtlichen Literal erstellen kann.

  • Kann ich die Präzision von Dezimalvariablen ohne Literale einstellen?
  • Wie kann ich B aus a erstellen? Wie kann ich B aus C erstellen?
War es hilfreich?

Lösung

Die Konservierung von nachlaufenden Nullen wie diese wurde in .NET 1.1 eingeführt, um eine strengere Konformität mit der ECMA -CLI -Spezifikation zu erhalten.

Es gibt einige Informationen dazu auf MSDN, z. B. hier.

Sie können die Präzision wie folgt einstellen:

  • Mathematik (oder Decke, Boden usw.), um die Präzision (b von c) zu verringern

  • Multiplizieren Sie mit 1.000 ... (mit der Anzahl der gewünschten Dezimalstellen), um die Präzision zu erhöhen - zB multiplizieren Sie sich mit 1,0 m, um B von a zu erhalten.

Andere Tipps

Sie sehen nur verschiedene Darstellungen der genauen Daten. Die Präzision von a decimal wird skaliert, um so groß zu sein, wie es sein muss (innerhalb von Grund).

Aus System.Decimal:

Eine Dezimalzahl ist ein Schwimmpunktwert, der aus einem Zeichen besteht, ein numerischer Wert, bei dem jede Ziffer im Wert von 0 bis 9 liegt, und Ein Skalierungsfaktor, der die Position eines schwebenden Dezimalpunkts angibt, der die integralen und fraktionalen Teile des numerischen Werts trennt.

Die binäre Darstellung eines Dezimalwerts besteht aus einem 1-Bit-Vorzeichen, einer 96-Bit-Ganzzahlzahl und einem Skalierungsfaktor, mit dem die 96-Bit-Ganzzahl geteilt und angeben, welcher Teil davon eine Dezimalanteile ist. Der Skalierungsfaktor ist implizit die Zahl 10, die auf einen Exponenten von 0 bis 28 erhöht wird. Daher ist die binäre Darstellung eines Dezimalwerts aus der Form (-296 zu 296) / 10(0 bis 28)), wo -296-1 ist gleich Minwert und 296-1 ist gleich MaxValue.

Der Skalierungsfaktor bewahrt auch alle nachfolgenden Nullen in einer Dezimalzahl. Nachfolgende Nullen beeinflussen keinen Einfluss auf den Wert einer Dezimalzahl in Arithmetik- oder Vergleichsoperationen. Nach der TOString -Methode können jedoch nachfolgende Nullen aufgedeckt werden, wenn eine geeignete Formatzeichenfolge angewendet wird.

Ich stellte fest, dass ich mit der Skala "manipulieren" konnte, indem ich mich durch eine Phantasie multiplizierte oder dividierte.

decimal a = 2m;
decimal c = 2.00000000m;
decimal PreciseOne = 1.000000000000000000000000000000m;
  //add maximum trailing zeros to a
decimal x = a * PreciseOne;
  //remove all trailing zeros from c
decimal y = c / PreciseOne;

Ich kann eine ausreichend präzise 1 herstellen, um Skalenfaktoren durch bekannte Größen zu ändern.

decimal scaleFactorBase = 1.0m;
decimal scaleFactor = 1m;
int scaleFactorSize = 3;

for (int i = 0; i < scaleFactorSize; i++)
{
  scaleFactor *= scaleFactorBase;
}

decimal z = a * scaleFactor;

Es ist verlockend zu verwirren decimal in SQL Server mit decimal in .net; Sie sind ganz anders.

Ein SQL -Server decimal ist eine Festpunktzahl, deren Genauigkeit und Skala festgelegt sind, wenn die Spalte oder Variable definiert ist.

EIN NETZ decimal ist eine schwimmende Punktzahl wie float und double (Der Unterschied ist das decimal Konservieren Sie die Dezimalstellen genau, während float und double Binäre Ziffern genau bewahren). Versuch, die Präzision von a .NET zu steuern decimal ist sinnlos, da alle Berechnungen die gleichen Ergebnisse liefern, unabhängig von der Anwesenheit oder Abwesenheit von Polsternullen.

Die Frage ist: Benötigen Sie wirklich die Präzision? gelagert im Dezimalwert, anstatt nur die Dezimalzahl auf die erforderliche Präzision anzuzeigen. Die meisten Anwendungen wissen intern, wie präzise sie sein möchten, und zeigen diese Präzision an. Selbst wenn ein Benutzer in einem Kontenpaket eine Rechnung für 100 für 100 eingibt, druckt er immer noch 100,00 mit etwas wie Val.ToString ("N2") aus.

Wie kann ich B aus a erstellen? Wie kann ich B aus C erstellen?

C bis B ist möglich.

Console.WriteLine(Math.Round(2.00000000m, 1)) 

produziert 2.0

A bis B ist schwierig, da das Konzept der Einführung der Präzision der Mathematik ein wenig fremd ist.

Ich denke, ein schrecklicher Hack könnte eine Hin- und Rückfahrt sein.

decimal b = Decimal.Parse(a.ToString("#.0"));
Console.WriteLine(b);

produziert 2.0

Dadurch werden alle nachfolgenden Nullen aus der Dezimalheit entfernt und Sie können dann nur verwenden ToString().

public static class DecimalExtensions
{
    public static Decimal Normalize(this Decimal value)
    {
        return value / 1.000000000000000000000000000000000m;
    }
}

Oder alternativ, wenn Sie eine genaue Anzahl von nachfolgenden Nullen wünschen, sagen wir 5, zuerst normalisieren () und dann mit 1,00000 m multiplizieren.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top