Qual o tamanho que uma string alocada na pilha precisa ter para armazenar qualquer float/double no formato% g?
int main()
{
float f;
double d;
char f_str[ ?? ];
char d_str[ ?? ];
sprintf(f_str, "%g", f);
sprintf(d_str, "%lg", d);
}
Editar:
Quero que o tamanho da string seja conhecido em tempo de compilação, de modo que não dependa de alocação de heap ou VLAs
Você pode usar snprintf() para calcular o comprimento exato necessário para sua string de formato e valores específicos
Isso depende do formato de ponto flutuante real e da localidade atual, pois alguns caracteres, como o caractere de ponto decimal, podem ocupar vários bytes. Por exemplo, se
double
corresponder ao formato IEEE 754 binary64 (também conhecido como precisão dupla), o comprimento máximo da string (como um número de bytes) é 13 no código do idioma C, mas pode ser 14 na prática (e eu nem acho que existe um limite do padrão C).Exemplo:
Na minha máquina Debian Linux (onde todas as localidades estão habilitadas), recebo:
O 14 é devido ao SEPARADOR DECIMAL ÁRABE U+066B usado para o caractere de ponto decimal no código de idioma ps_AF (baseado em UTF-8), codificado como D9 AB.
A resposta é semelhante para
long double
, mas você precisa saber os expoentes mínimo e máximo do formato associado.13 quando os valores estão dentro de 10 +/- 999
15 com binário128
Para valores extremos
"%g"
, utiliza notação exponencial."%g"
, sem largura ou precisão, será impresso com 6 dígitos significativos.Forma há muito esperada:
Exemplo:
quando
double
tem uma faixa de expoentes mais ampla, é necessário espaço adicional.NAN pode imprimir algo mais longo. Muito está definido para implementação. Um pior caso razoável seria estimá-lo como "-sNAN" carga útil decimal " A carga útil de binary64 pode ter 16 casas decimais.
Se a busca por uma constante , dado o intervalo de expoentes, em decimal, puder ter mais de 3 dígitos e as NANs puderem imprimir uma carga útil, eu escalaria a impressão da carga útil da NAN, pois esse é certamente o pior caso. Use o tamanho do significando em bits para determinar a carga decimal escalonando por log10(2).
Portanto, um tamanho de buffer de 22 para common
double
.Considerando todos os atributos de definição de implementação em potencial, eu usaria
snprintf()
.