Domanda

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

Genera questa uscita:

2
2.0
2.00000000
2.000000000000000000000000000

Così posso vedere che la creazione di una variabile decimale da un letterale mi permette di controllare la precisione.

  • Posso regolare la precisione delle variabili decimali senza usare letterali?
  • Come si può creare b da un? Come posso creare b da c?
È stato utile?

Soluzione

Preservare zeri finali come questo è stato introdotto nel .NET 1.1 per più stretta conformità con la specifica ECMA CLI.

C'è un po 'di informazioni su MSDN, ad esempio, qui .

È possibile regolare la precisione nel seguente modo:

  • Math.round (oa soffitto, pavimento ecc) per diminuire la precisione (b da c)

  • Moltiplicare per 1.000 ... (con il numero di decimali che si desidera) per aumentare la precisione - per esempio moltiplicare per 1,0 M per ottenere b da un.

Altri suggerimenti

Si sono appena vedendo diverse rappresentazioni degli stessi dati esatti. La precisione di un decimal verrà dimensionata per essere grande come deve essere (entro limiti ragionevoli).

System.Decimal :

  

Un numero decimale è una virgola mobile   valore che è costituito da un segno, un   valore numerico dove ogni cifra del   valore varia da 0 a 9, e un   fattore di scala che indica la   posizione di un punto decimale fluttuante   che separa l'integrale e   parti frazionarie del valore numerico.

     

La rappresentazione binaria di un numero decimale   il valore è costituito da un segno a 1 bit, un   numero intero 96 bit, e una scalatura   fattore utilizzato per dividere il 96 bit   intero e specificare quale porzione di essa   è una frazione decimale. la scala   fattore è implicitamente il numero 10,   elevata a un esponente compreso tra 0   a 28. Pertanto, il binario   rappresentazione di un valore decimale è   della forma, ((-2 96 2 96 ) / 10 (da 0 a   28) ), dove -2 96 -1 è uguale a   MinValue e 2 96 -1 è uguale a   MaxValue.

     

Il fattore di scala conserva anche qualsiasi   zeri finali in un numero decimale.   zeri finali non influiscono sulla   valore di un numero decimale   operazioni aritmetiche o di confronto.   Tuttavia, zeri finali possono essere   rivelata dal metodo ToString se un   viene applicato appropriata stringa di formato.

ho scoperto che potevo "tamper" con la scala moltiplicando o dividendo per una fantasia 1.

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;

posso fabbricare sufficientemente precisa 1 per modificare i fattori di scala dai formati noti.

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

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

decimal z = a * scaleFactor;

E 'forte la tentazione di confondere i decimal in SQL Server con decimal in .NET; essi sono molto diversi.

A decimal SQL Server è un numero a virgola fissa la cui precisione e scala sono fissi quando la colonna o variabile è definita.

A decimal NET è un numero a virgola mobile come float e double (la differenza che decimal conserva accuratamente cifre decimali che float e double preservare accuratamente cifre binarie). Tentare di controllare la precisione di un decimal NET è inutile, dal momento che tutti i calcoli produrranno gli stessi risultati indipendentemente dalla presenza o assenza di zeri imbottitura.

La domanda è - non si ha realmente bisogno la precisione memorizzato nel decimale, piuttosto che visualizzare il decimale alla precisione richiesta. La maggior parte delle applicazioni sanno internamente come precisa vogliono essere e visualizzare a quel livello di precisione. Ad esempio, anche se un utente inserisce una fattura per 100 in un pacchetto di conti, esso stampa ancora fuori da 100.00 usando qualcosa come val.ToString ( "n2").

  

Come posso creare b da un? Come posso creare b da c?

c a B è possibile.

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

produce 2.0

A a B è difficile in quanto il concetto di introdurre la precisione è un piccolo alieno alla matematica.

Credo che un orribile hack potrebbe essere un viaggio di andata.

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

produce 2.0

Questo eliminerà tutti i zeri finali del decimale e quindi si può semplicemente utilizzare ToString().

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

In alternativa, se si desidera che un numero esatto di zeri finali, diciamo 5, prima Normalizzare () e poi moltiplicare per 1.00000m.

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