Formatação dupla como string em C #

votos
9

Eu tenho um casal que pode ter um valor de cerca de 0.000001 para 1,000,000,000.000

Desejo para formatar esse número como uma string, mas condicionalmente dependendo do seu tamanho. Então, se é muito pequena eu quero formatá-lo com algo como:

String.Format({0:.000000000}, number);

se não é que pequena, digamos 0,001 então eu quero usar algo como

String.Format({0:.00000}, number);

e se é mais, digamos, 1.000, em seguida, formatá-lo como:

String.Format({0:.0}, number);

Existe uma maneira inteligente de construir essa cadeia de formato com base no tamanho do valor que eu vou formatar?

Publicado 10/12/2008 em 04:36
fonte usuário
Em outras línguas...                            


5 respostas

votos
15

Use Math.Log10 do valor absoluto da dupla para descobrir quantos de 0 você precisa de esquerda (se positivo) ou direita (se negativo) da casa decimal. Escolha a cadeia de formato com base neste valor. Você vai precisar lidar com valores zero separadamente.

string s;
double epislon = 0.0000001; // or however near zero you want to consider as zero
if (Math.Abs(value) < epislon) {
    int digits = Math.Log10( Math.Abs( value ));
    // if (digits >= 0) ++digits; // if you care about the exact number
    if (digits < -5) {
       s = string.Format( "{0:0.000000000}", value );
    }
    else if (digits < 0) {
       s = string.Format( "{0:0.00000})", value );
    }
    else {
       s = string.Format( "{0:#,###,###,##0.000}", value );
    }
}
else {
    s = "0";
}

Ou construir dinamicamente com base no número de dígitos.

Respondeu 10/12/2008 em 04:48
fonte usuário

votos
2

No seguimento (tvanfosson e pela "extensão") OwenP de:

Se é bastante comum, e você está no C # 3.0, eu transformá-lo em um método de extensão no dobro:

class MyExtensions 
{
    public static string ToFormmatedString(this double d)
    {
        // Take d and implement tvanfosson's code
    }
}

Agora qualquer lugar você tem um duplo você pode fazer:

double d = 1.005343;
string d_formatted = d.ToFormattedString();
Respondeu 11/04/2009 em 19:49
fonte usuário

votos
2

Os dois primeiros String.Format na sua pergunta pode ser resolvido removendo automaticamente zeros à direita:

String.Format("{0:#,##0.########}", number);

E o último que você poderia resolver chamando Math.Round (número, 1) para valores superiores a 1000 e, em seguida, usar o mesmo String.Format.

Algo como:

String.Format("{0:#,##0.########}", number<1000 ? number : Math.Round(number,1));
Respondeu 10/12/2008 em 14:53
fonte usuário

votos
2

Use o caractere # para posições opcionais na string:

string.Format("{0:#,###,##0.000}", number);

Eu não acho que você pode controlar o número de casas decimais assim como a precisão da dupla provavelmente vai bagunçar as coisas.

Para encapsular a lógica de decidir quantas casas decimais para a saída você pode olhar para a criação de um formatador personalizado.

Respondeu 10/12/2008 em 04:42
fonte usuário

votos
1

Se fosse comigo, eu ia escrever uma classe wrapper personalizado e colocar o código de tvanfosson em seu ToStringmétodo. Dessa forma, você ainda pode trabalhar com o valor duplo, mas você deseja obter a representação de cadeia direita em praticamente todos os casos. Seria algo parecido com isto:

class FormattedDouble
{ 
    public double Value { get; set; }

    protected overrides void ToString()
    {
        // tvanfosson's code to produce the right string
    }
}

Talvez poderia ser melhor para torná-lo um struct, mas eu duvido que ele iria fazer uma grande diferença. Você pode usar a classe como este:

var myDouble = new FormattedDouble();
myDouble.Value = Math.Pi;
Console.WriteLine(myDouble);
Respondeu 11/12/2008 em 00:36
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more