Eu quero analisar uma string como "3.5"
uma dupla. Contudo,
double.Parse("3.5")
produz 35 e
double.Parse("3.5", System.Globalization.NumberStyles.AllowDecimalPoint)
joga um FormatException
.
Agora, a localidade do meu computador está definida como alemão, em que uma vírgula é usada como separador decimal. Pode ter algo a ver com isso e double.Parse()
esperar "3,5"
como entrada, mas não tenho certeza.
Como posso analisar uma sequência contendo um número decimal que pode ou não ser formatado conforme especificado no meu código de idioma atual?
Respostas:
fonte
XmlConvert
classe ... você tem alguma idéia de que isso é melhor, pior e / ou diferente do que usarCultureInfo.InvariantCulture
?XmlConvert
não se destina realmente a ser usado para analisar um único valor duplo no código. Eu prefiro usardouble.Parse
ouConvert.ToDouble
que tornem minha intenção óbvia.Normalmente, uso uma função multicultural para analisar a entrada do usuário, principalmente porque se alguém está acostumado ao numpad e está usando uma cultura que usa vírgula como separador decimal, essa pessoa usará o ponto do numpad em vez de vírgula.
Cuidado, porém, os comentários do @nikie são verdadeiros. Para minha defesa, uso essa função em um ambiente controlado, onde sei que a cultura pode ser en-US, en-CA ou fr-CA. Uso essa função porque, em francês, usamos a vírgula como um separador decimal, mas quem já trabalhou em finanças sempre usará o separador decimal no teclado numérico, mas esse é um ponto, não uma vírgula. Portanto, mesmo na cultura fr-CA, preciso analisar o número que terá um ponto como separador decimal.
fonte
Não consegui escrever um comentário, então escrevo aqui:
double.Parse ("3.5", CultureInfo.InvariantCulture) não é uma boa ideia, porque no Canadá escrevemos 3,5 em vez de 3,5 e essa função nos fornece 35 como resultado.
Eu testei os dois no meu computador:
Esta é a maneira correta que Pierre-Alain Vigeant mencionou
fonte
Substitua a vírgula por um ponto antes de analisar. Útil em países com vírgula como separador decimal. Pense em limitar a entrada do usuário (se necessário) a uma vírgula ou ponto.
fonte
O truque é usar a cultura invariável, para analisar pontos em todas as culturas.
fonte
Olha, toda resposta acima que propõe escrever uma substituição de string por uma string constante só pode estar errada. Por quê? Porque você não respeita as configurações de região do Windows! O Windows garante ao usuário a liberdade de definir o caractere separador que ele deseja. Ele pode abrir o painel de controle, entrar no painel de região, clicar em avançado e alterar o caracter a qualquer momento. Mesmo durante a execução do seu programa. Pense nisso. Uma boa solução deve estar ciente disso.
Então, primeiro você terá que se perguntar, de onde vem esse número, que deseja analisar. Se for proveniente de entrada no .NET Framework, não há problema, pois estará no mesmo formato. Mas talvez tenha vindo de fora, talvez de um servidor externo, talvez de um banco de dados antigo que ofereça suporte apenas às propriedades da string. Lá, o administrador do banco de dados deve ter fornecido uma regra em que formato os números devem ser armazenados. Se você souber, por exemplo, que será um banco de dados dos EUA com o formato dos EUA, use este trecho de código:
Isso funcionará bem em qualquer lugar do mundo. E por favor não use 'Convert.ToXxxx'. A classe 'Converter' é considerada apenas uma base para conversões em qualquer direção. Além disso: você também pode usar o mecanismo semelhante para o DateTimes.
fonte
fonte
Meus dois centavos neste tópico, tentando fornecer um método genérico de dupla conversão:
Funciona como esperado com:
Nenhuma conversão padrão é implementado, por isso seria um fracasso tentando analisar
1.3,14
,1,3.14
ou casos semelhantes.fonte
O código a seguir faz o trabalho em qualquer cenário. É um pouco de análise.
fonte
Acho que a conversão 100% correta não é possível se o valor vier de uma entrada do usuário. por exemplo, se o valor for 123.456, pode ser um agrupamento ou um ponto decimal. Se você realmente precisa de 100%, deve descrever seu formato e lançar uma exceção, se não estiver correta.
Mas eu aprimorei o código do JanW, para chegarmos um pouco mais à frente nos 100%. A idéia por trás disso é que, se o último separador for um groupSeperator, esse seria mais um tipo inteiro do que um duplo.
O código adicionado está no primeiro se de GetDouble .
fonte
fonte
Em vez de precisar especificar um código de idioma em todas as análises, prefiro definir um código de idioma em todo o aplicativo, embora se os formatos de sequência não sejam consistentes no aplicativo, isso pode não funcionar.
Definir isso no início do seu aplicativo fará com que todas as análises duplas esperem uma vírgula como delimitador decimal. Você pode definir um código de idioma apropriado para que o separador decimal e milhares se ajuste às seqüências de caracteres que você está analisando.
fonte
É difícil sem especificar qual separador decimal procurar, mas se você o fizer, é isso que estou usando:
Isso deve funcionar com qualquer cultura. Falha na análise correta de cadeias de caracteres que possui mais de um separador decimal, diferente das implementações que substituem em vez da troca.
fonte
Melhorei o código de @JanW também ...
Eu preciso dele para formatar os resultados dos instrumentos médicos, e eles também enviam "> 1000", "23.3e02", "350E-02" e "NEGATIVO".
fonte
fonte
Eu acho que é a melhor resposta:
fonte
O abaixo é menos eficiente, mas eu uso essa lógica. Isso é válido apenas se você tiver dois dígitos após o ponto decimal.
fonte
Multiplique o número e divida-o pelo que você multiplicou antes.
Por exemplo,
fonte