2010-04-26 4 views
17

Ho notato che .NET ha un comportamento funky/non intuitivo quando si tratta di decimali e zeri finali.Decimale - troncare gli zero finali

0m == 0.000m //true 
0.1m == 0.1000m //true 

ma

(0m).ToString() == (0.000m).ToString() //false 
(0.1m).ToString() == (0.1000m).ToString() //false 

so di necessità di rispettare lo standard ECMA CLI. Tuttavia vorrei sapere se esiste un modo incorporato per troncare gli zero finali per un valore decimale senza passare attraverso la rappresentazione di stringhe (.ToString ("G29") e il trucco back-up dovrebbe funzionare, ma non è né una soluzione rapida né elegante)?

Qualche idea? Grazie mille.

+0

Hmmm ... Sto pensando a qualcosa che coinvolge 'decimal.GetBits' e aritmetica a 96 bit, ma non semplice. –

+1

Vedere http://stackoverflow.com/questions/1584314/ per una domanda correlata. Una delle risposte dà il trucco di dividere per 1.000 .... 0000m per rimuovere efficacemente gli zero finali (presumibilmente perché l'esponente 'ideale' per un quoziente x/y è la differenza degli esponenti di x e y). È sorprendente che non esista un metodo 'normalize', comunque. –

risposta

16

Penso che quello che vi serve è questo (per ulteriori dettagli la mia risposta here):

public static decimal Normalize(decimal value) 
{ 
    return value/1.000000000000000000000000000000000m; 
} 
+0

Questo è il più veloce che ho incontrato e batte i miei tentativi di giocata binaria, anche se hanno battuto facilmente tutti gli altri contendenti qui, incluso [questo approccio in qualche modo simile] (http://stackoverflow.com/a/20647024/709537) su una [domanda duplicata] (http://stackoverflow.com/q/4525854/709537). –

7

utilizzare una stringa di formato per specificare l'output di ToString():

(0.1m).ToString("0.#") -> "0.1" 
(0.10000m).ToString("0.#") -> "0.1" 

usare un "0" nel formato per specificare una cifra o un non-significate 0, usare "#" per specificare un cifra significativa o soppressione aa 0 non significativa.

Modifica: presumo che tu sia preoccupato per la rappresentazione visiva (stringa) del numero - in caso contrario, rimuoverò la mia risposta.

+1

Non mi interessa molto della rappresentazione visiva. Il problema è che quando passo quei valori al motore JScript, per qualche motivo viene incasinato dai valori di tipo 1.0000m. Comunque per la risposta comunque. Post scriptum 0.10000m.ToString ("G29") funziona per qualsiasi numero di cifre significative. – Konrad

+1

Questo arrotonderà anche il valore, ad esempio 123.4567 con 0. # applicato diventa 123.5 – CRice

3

non mi piace molto, ma funziona (per qualche intervallo di valori, almeno) ...

static decimal Normalize(decimal value) 
    { 
     long div = 1; 
     while(value - decimal.Truncate(value) != 0) 
     { 
      div *= 10; 
      value *= 10; 
     } 
     if(div != 1) { 
      value = (decimal)(long)value/div; 
     } 
     return value; 
    } 
+0

Funziona nella maggior parte dei casi. Sfortunatamente non funziona per il tipo di valori di 0,00000 m. Avrebbe bisogno di un altro 'se' per verificare lo zero decimale e questo renderebbe ancora più complicato. – Konrad