Veja minha resposta: String.Format()com 'G', você deve obter o que deseja. Atualizei minha resposta com um link para os formatos numéricos padrão. Muito usuário.
Dog Ears
3
Um decimal pode ser convertido em double, e o padrão ToStringpara double emite os zeros à direita. leia isto
Shimmy Weitzhandler
2
E provavelmente custará menos desempenho (intervalos de uma quantidade muito grande de registros) do que passar o "G" como um formato de string para a ToStringfunção.
Shimmy Weitzhandler
4
Você não deve converter um decimal em um dobro, pois perderá o significado e poderá introduzir poder de duas imprecisões de arredondamento.
19415 kristianp
Respostas:
167
Não é tão simples assim, se a entrada é uma string? Você pode usar um destes:
Atualização Confira os formatos numéricos padrão que tive que definir explicitamente o especificador de precisão para 29, conforme os documentos afirmam claramente:
No entanto, se o número for um decimal e o especificador de precisão for omitido, a notação de ponto fixo será sempre usada e os zeros à direita serão preservados
Cuidado com valores como 0,000001. O formato G29 os apresentará da maneira mais curta possível, para mudar para a notação exponencial. string.Format("{0:G29}", decimal.Parse("0.00000001",System.Globalization.CultureInfo.GetCultureInfo("en-US")))dará "1E-08" como resultado.
De todas as respostas, você teve o mínimo de etapas envolvidas. Obrigado orelhas de cão.
Zo tem
4
var d = 2,0 m; d.ToString ("G");
Dave Hillier 31/01
3
@ Dave Hillier - Entendo, corrigi minha resposta. Felicidades. [adicionado "especificador de precisão" explícito]
Dog Orars
16
Cuidado com valores como 0,000001. O formato G29 os apresentará da maneira mais curta possível, para mudar para a notação exponencial. string.Format ("{0: G29}", decimal.Parse ("0.00000001", System.Globalization.CultureInfo.GetCultureInfo ("en-US"))) fornecerá "1E-08" como resultado
Konrad em
15
@ Konrad - existe uma maneira de evitar a notação científica de números com 5 ou 6 casas decimais?
Jill
202
Corri para o mesmo problema, mas em um caso em que não tenho controle da saída para string, que foi resolvida por uma biblioteca. Depois de analisar os detalhes na implementação do tipo Decimal (consulte http://msdn.microsoft.com/en-us/library/system.decimal.getbits.aspx ), criei um truque interessante (aqui como uma extensão método):
Essa resposta é sua, porque, diferentemente de todas as outras respostas sobre essa questão (e até mesmo todo o assunto), na verdade, FUNCIONA e faz o que o OP está pedindo.
Coxy
2
o número de 0s é uma quantidade exata aqui ou apenas para cobrir os valores mais esperados?
Simon_Weaver 23/09
3
O MSDN declara "O fator de escala é implicitamente o número 10, aumentado para um expoente que varia de 0 a 28", que eu entendo como o número decimal terá no máximo 28 dígitos além do ponto decimal. Qualquer número de zeros> = 28 deve funcionar.
Thomas Materna
2
Esta é a melhor resposta! O número na resposta tem 34 algarismos, 1seguido de 33- 0s, mas isso cria exatamente a mesma decimalinstância de um número com 29 algarismos, um 1e 28- 0s. Assim como @ThomasMaterna disse em seu comentário. Não System.Decimalpode ter mais de 29 algarismos (números com dígitos iniciais maiores que 79228...apenas 28 algarismos no total). Se você quiser mais zeros à direita, multiplique em 1.000...mvez de dividir. Além disso, Math.Roundpode cortar alguns zeros, por exemplo , Math.Round(27.40000m, 2)dá 27.40m, restando apenas um zero.
Jeppe Stig Nielsen
2
Grande truque, mas não funciona em Mono e não é guarantueed ao trabalho em versões de recurso do .NET
Não é uma resposta. Você não está removendo zeros à direita, está removendo a precisão. O método proposto num1.ToString("0.##")deve retornar 13.1534545765(sem alteração) porque não há zeros à direita.
Jan 'splite' K.
E é exatamente por isso que estou exibindo as respostas para minhas três entradas propostas, para que os usuários possam ver como minha solução funciona.
Fizzix
Ele não responde à pergunta mesmo se você listar as entradas propostas.
Dave Friedel
2
Eu gostaria de votar isso 10 vezes, se eu pudesse. Exatamente o que eu precisava!
precisa saber é o seguinte
1
Resposta perfeita para a pergunta. Melhor resposta na minha opinião. Comentar que remove a precisão está correto, mas esse não foi o problema. Mais importante - é o que eu preciso. Meus usuários normalmente inserem números inteiros, talvez algo como 2,5, mas eu preciso suportar três dígitos além do ponto decimal. Então, eu quero dar a eles o que eles entraram, não com um monte de zeros que eles não entraram. por exemplo, Console.Write ($ "num3 = {num3: 0. ##}"); => num3 = 30
Observe que, se vestiver 0m, o resultado do seu código será uma sequência vazia em vez de "0".
Sam
2
Sim. Deve ser "0. ########".
PRMan
2
Uma abordagem de nível muito baixo, mas acredito que essa seria a maneira mais eficiente de usar apenas cálculos inteiros rápidos (e nenhum método de análise de seqüência lenta e métodos sensíveis à cultura):
publicstaticdecimalNormalize(thisdecimal d){int[] bits =decimal.GetBits(d);int sign = bits[3]&(1<<31);int exp =(bits[3]>>16)&0x1f;uint a =(uint)bits[2];// Top bitsuint b =(uint)bits[1];// Middle bitsuint c =(uint)bits[0];// Bottom bitswhile(exp >0&&((a %5)*6+(b %5)*6+ c)%10==0){uint r;
a =DivideBy10((uint)0, a,out r);
b =DivideBy10(r, b,out r);
c =DivideBy10(r, c,out r);
exp--;}
bits[0]=(int)c;
bits[1]=(int)b;
bits[2]=(int)a;
bits[3]=(exp <<16)| sign;returnnewdecimal(bits);}privatestaticuintDivideBy10(uint highBits,uint lowBits,outuint remainder){ulong total = highBits;
total <<=32;
total = total |(ulong)lowBits;
remainder =(uint)(total %10L);return(uint)(total /10L);}
@ Damien, sim, e observe que, para essas puroposes (você não sentirá nada a menos que faça um bilhão de registros), primeiro porque double é mais rápido, segundo, porque passar um formato de string para a função ToString custa mais desempenho do que não passando parâmetros. novamente, você não sentirá nada a menos que trabalhe em bilhões de registros.
Shimmy Weitzhandler
1
Você não precisa especificar G, porque double.ToStringremove zeros à direita por padrão.
Shimmy Weitzhandler
4
Cuidado com valores como 0,000001. Estes serão apresentados na notação exponencial. double.Parse ("0.00000001", System.Globalization.CultureInfo.GetCultureInfo ("en-US")). ToString () fornecerá "1E-08" como resultado
Konrad em
17
NUNCA faça isso. Normalmente, o motivo de você ter um número decimal é porque você está representando um número com precisão (não exatamente como o dobro). É verdade que esse erro de ponto flutuante é provavelmente muito pequeno, mas pode resultar na exibição de números incorretos, no entanto
Adam Tegen 13/13
2
Ai, converter um tipo de dados de 128 bits (decimal) em um tipo de dados de 64 bits (duplo) para formatação, não é uma boa ideia!
Depende do que o seu número representa e como você deseja gerenciar os valores: é uma moeda, você precisa de arredondamento ou truncamento, precisa desse arredondamento apenas para exibição?
Se, para exibição, considere a formatação, os números são x.ToString ("")
privatestaticdecimalTrim(thisdecimalvalue){var s =value.ToString(CultureInfo.InvariantCulture);return s.Contains(CultureInfo.InvariantCulture.NumberFormat.NumberDecimalSeparator)?Decimal.Parse(s.TrimEnd('0'),CultureInfo.InvariantCulture):value;}privatestaticdecimal?Trim(thisdecimal?value){returnvalue.HasValue?(decimal?)value.Value.Trim():null;}privatestaticvoidMain(string[] args){Console.WriteLine("=>{0}",1.0000m.Trim());Console.WriteLine("=>{0}",1.000000023000m.Trim());Console.WriteLine("=>{0}",((decimal?)1.000000023000m).Trim());Console.WriteLine("=>{0}",((decimal?)null).Trim());}
(I) -> Analisar valor decimal de qualquer fonte de string.
(II) -> Primeiro: lance para dobrar e remova os zeros à direita. Segundo: Outra conversão para decimal porque não existe conversão implícita de decimal para dupla e vice-versa)
não é uma opção em comparação com outras abordagens neste post. Convertendo para string e volta é sempre ruim opção para manipular números (pelo menos por causa do locale)
Vladimir Semashkin
-11
tente assim
string s ="2.4200";
s = s.TrimStart('0').TrimEnd('0','.');
você pode usar subString()método para isso, mas de acordo com pergunta postada aqui, eu não vejo nenhuma exigência como essa =)
Singleton
2
E as localidades que não usam '.'
Dave Hillier 31/01
10
Isso falha miseravelmente para números que são múltiplos múltiplos de 10,0.
Ben Voigt
1
O que o @BenVoigt disse está totalmente correto, pois o exame "12300.00"será aparado "123". Outro efeito que parece indesejável é que alguns números, como por exemplo, "0.00"são cortados até a cadeia vazia ""(embora esse número seja um caso especial de ser um "múltiplo de 10,0" integral).
String.Format()
com 'G', você deve obter o que deseja. Atualizei minha resposta com um link para os formatos numéricos padrão. Muito usuário.double
, e o padrãoToString
para double emite os zeros à direita. leia istoToString
função.Respostas:
Não é tão simples assim, se a entrada é uma string? Você pode usar um destes:
Isso deve funcionar para todas as entradas.
Atualização Confira os formatos numéricos padrão que tive que definir explicitamente o especificador de precisão para 29, conforme os documentos afirmam claramente:
A atualização Konrad apontou nos comentários:
fonte
Corri para o mesmo problema, mas em um caso em que não tenho controle da saída para string, que foi resolvida por uma biblioteca. Depois de analisar os detalhes na implementação do tipo Decimal (consulte http://msdn.microsoft.com/en-us/library/system.decimal.getbits.aspx ), criei um truque interessante (aqui como uma extensão método):
A parte do expoente do decimal é reduzida para apenas o necessário. Chamar ToString () no decimal de saída escreverá o número sem nenhum 0. à direita.
fonte
1
seguido de 33-0
s, mas isso cria exatamente a mesmadecimal
instância de um número com 29 algarismos, um1
e 28-0
s. Assim como @ThomasMaterna disse em seu comentário. NãoSystem.Decimal
pode ter mais de 29 algarismos (números com dígitos iniciais maiores que79228...
apenas 28 algarismos no total). Se você quiser mais zeros à direita, multiplique em1.000...m
vez de dividir. Além disso,Math.Round
pode cortar alguns zeros, por exemplo ,Math.Round(27.40000m, 2)
dá27.40m
, restando apenas um zero.Na minha opinião, é mais seguro usar seqüências de formato numérico personalizadas .
fonte
Eu uso esse código para evitar a notação científica "G29":
EDIT: usando o sistema CultureInfo.NumberFormat.NumberDecimalSeparator:
fonte
Culture.NumberFormat.NumberDecimalSeparator
Use o
#
símbolo de hash ( ) para exibir apenas os zeros à direita quando necessário. Veja os testes abaixo.fonte
num1.ToString("0.##")
deve retornar13.1534545765
(sem alteração) porque não há zeros à direita.Encontrei uma solução elegante de http://dobrzanski.net/2009/05/14/c-decimaltostring-and-how-to-get-rid-of-trailing-zeros/
Basicamente
fonte
v
estiver0m
, o resultado do seu código será uma sequência vazia em vez de"0"
.Uma abordagem de nível muito baixo, mas acredito que essa seria a maneira mais eficiente de usar apenas cálculos inteiros rápidos (e nenhum método de análise de seqüência lenta e métodos sensíveis à cultura):
fonte
a
eb
) em toda a iteração, se todas forem zero. No entanto, encontrei esta solução surpreendentemente simples que também supera facilmente o que você e eu criamos em termos de desempenho .Isso funcionará:
Ou se o seu valor inicial for
string
:Preste atenção a este comentário .
fonte
double.ToString
remove zeros à direita por padrão.Isto é simples.
Testado.
Felicidades :)
fonte
Depende do que o seu número representa e como você deseja gerenciar os valores: é uma moeda, você precisa de arredondamento ou truncamento, precisa desse arredondamento apenas para exibição?
Se, para exibição, considere a formatação, os números são x.ToString ("")
http://msdn.microsoft.com/en-us/library/dwhawy9k.aspx e
http://msdn.microsoft.com/en-us/library/0c899ak8.aspx
Se for apenas um arredondamento, use a sobrecarga Math.Round que requer uma sobrecarga MidPointRounding
http://msdn.microsoft.com/en-us/library/ms131274.aspx )
Se você obtiver seu valor de um banco de dados, considere converter em vez de converter: double value = (decimal) myRecord ["columnName"];
fonte
Você pode apenas definir como:
fonte
Caso deseje manter o número decimal, tente o seguinte exemplo:
fonte
Tentando fazer uma solução mais amigável do DecimalToString ( https://stackoverflow.com/a/34486763/3852139 ):
Resultado:
fonte
Resposta muito simples é usar TrimEnd (). Aqui está o resultado,
A saída é 1 Se meu valor for 1,01, minha saída será 1,01
fonte
value = 100
?O código a seguir pode ser usado para não usar o tipo de sequência:
Retorna 789,5
fonte
Truncar Zeros à direita é muito fácil, resolva com uma conversão duplex:
(I) -> Analisar valor decimal de qualquer fonte de string.
(II) -> Primeiro: lance para dobrar e remova os zeros à direita. Segundo: Outra conversão para decimal porque não existe conversão implícita de decimal para dupla e vice-versa)
fonte
tente este código:
fonte
tente assim
e depois converta isso para flutuar
fonte
subString()
método para isso, mas de acordo com pergunta postada aqui, eu não vejo nenhuma exigência como essa =)"12300.00"
será aparado"123"
. Outro efeito que parece indesejável é que alguns números, como por exemplo,"0.00"
são cortados até a cadeia vazia""
(embora esse número seja um caso especial de ser um "múltiplo de 10,0" integral).