Pergunta

Estou imprimindo uma variável, digamos Z1, que é uma matriz 1-D contendo números de ponto flutuante em um arquivo de texto para que eu possa importar para o MATLAB ou GNUPLOT para plotagem. Ouvi dizer que os arquivos binários (.dat) são menores que os arquivos .txt. A definição que eu uso atualmente para imprimir para um arquivo .txt é:

void create_out_file(const char *file_name, const long double *z1, size_t z_size){
FILE *out;
size_t i;
 if((out = _fsopen(file_name, "w+", _SH_DENYWR)) == NULL){
 fprintf(stderr, "***> Open error on output file %s", file_name);
 exit(-1);
 }
for(i = 0; i < z_size; i++)
fprintf(out, "%.16Le\n", z1[i]);
fclose(out);
}   

Eu tenho três perguntas:

  1. Os arquivos binários são realmente mais compactos do que os arquivos de texto?;

  2. Se sim, gostaria de saber como modificar o código acima para poder imprimir os valores da matriz Z1 em um arquivo binário. Eu li que o FPRINTF precisa ser substituído pelo FWRITE. Meu arquivo de saída diz que o DODO.dat deve conter os valores da matriz Z1 com um número flutuante por linha.

  3. Eu tenho %.16Le no meu código, mas acho que %.15LE está certo, pois tenho 15 dígitos de precisão com o longo dobro. Eu coloquei um ponto (.) Na posição de largura, pois acredito que isso permite que a expansão para um campo arbitrário mantenha o número desejado. Estou certo? Como exemplo com %.16LE, posso ter uma saída como 1.0047914240730432E-002, o que me dá 16 dígitos de precisão e a largura do campo tem a largura correta para exibir o número corretamente. A colocação de um ponto (.) Na posição de largura está em vez de um valor de largura uma boa prática?

Muito obrigado...

ATUALIZAR Está mudando para:

for(i = 0; i < z_size; i++)
fwrite(&z1, sizeof(long double), 1, out);

Ok, além da mudança para "WB+"? Não consigo ler o arquivo binário no MATLAB.

Foi útil?

Solução

  1. Sim, os arquivos binários são mais compactos, mas você perde a portabilidade e há vários outros problemas em potencial, portanto, a menos que seus arquivos de dados sejam problemáticos ou lentos para exportar/importar, é uma boa ideia manter o texto se você puder (você sempre pode comprimi -los para armazenamento, por exemplo, com zip)

  2. Abra seu arquivo com "WB" em vez de "W" e use fwrite() - Você não tem mais "linhas" em seu arquivo - será apenas um fluxo de valores de ponto flutuante (binário)

  3. Você pode estar ficando confuso entre double e long double - uma long double pode ter até 16 bytes de tamanho e ter uma precisão de até 32 dígitos (no entanto, isso é dependente da implementação - o duplo longo pode geralmente ser de 10, 12 ou 16 bytes). UMA double é geralmente 8 bytes e tem uma precisão de cerca de 16 dígitos.

Matlab pode não ser capaz de lidar com long double (como não é bem padronizado), provavelmente você só quer escrever duplas em seu arquivo de dados, por exemplo

for (i = 0; i < z_size; i++)
{
    double z = (double)z1[i];
    fwrite(&z, sizeof(double), 1, out);
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top