Pergunta

As minhas exportações de aplicativos clientes e importações algumas variáveis ??do tipo real através de um arquivo de texto usando writeln e readln. Eu tentei aumentar a largura dos campos escritos até os olhares código como:

writeln(file, exportRealvalue:30); //using excess width of field
....
readln(file, importRealvalue);

Quando eu exportar e importar e exportar novamente e comparar os arquivos eu recebo uma diferença nos dois últimos dígitos, por exemplo (pode ser desligado no número real de dígitos aqui, mas você obtê-lo):

-1.23456789012E-0002
-1.23456789034E-0002

Isso realmente faz a diferença no aplicativo para que o cliente quer saber o que eu possa fazer sobre isso. Agora eu não tenho certeza que é apenas o de leitura / gravação que faz isso, mas eu pensei que eu ia jogar uma pergunta rápida lá fora antes de eu mergulhar no hey pilha novamente. Preciso ir binário sobre isso?

Este não é um aplicativo lidar com moeda ou algo assim, eu só escrever e ler os valores de / para arquivo. Sei pontos flutuantes às vezes são um pouco estranhos e eu pensei que uma das rotinas (writeln / readln) pode ter algum negócio engraçado acontecendo.

Foi útil?

Solução

Se você quiser especificar a precisão de um real com um WriteLn, use o seguinte:

WriteLn(RealVar:12:3);

Ele produz o valor Realvar com pelo menos 12 posições e uma precisão de 3.

Outras dicas

Você pode tentar mudar para para a precisão estendida maior. Como foi salientado, porém, números de ponto flutuante só tem tantos dígitos significativos de precisão, por isso ainda é possível exibir mais dígitos, em seguida, são armazenados com precisão, o que poderia resultar no comportamento especificado.

A partir da ajuda Delphi:

Win32 Fundamental tipos reais

                                            | Significant | Size in 
Type     | Range                            | digits      | bytes
---------+----------------------------------+-------------+----------
Real     | -5.0 x 10^–324 .. 1.7 x 10^308   | 15–16       |   8  
Real48   | -2.9 x 10^–39 .. 1.7 x 10^38     | 11-12       |   6   
Single   | -1.5 x 10^–45 .. 3.4 x 10^38     |  7-8        |   4   
Double   | -5.0 x 10^–324 .. 1.7 x 10^308   | 15-16       |   8   
Extended | -3.6 x 10^–4951 .. 1.1 x 10^4932 | 10-20       |  10   
Comp     | -2^63+1 .. 2^63–1                | 10-20       |   8   
Currency | -922337203685477.5808..          |             | 
                    922337203685477.5807    | 10-20       |   8   

Nota : O seis-byte Real48 tipo foi chamado real em versões anteriores do Object Pascal. Se você está recompilar o código que usa a mais velha, de seis bytes tipo real em Delphi, você pode querer mudá-lo para Real48 . Você também pode usar a diretiva {$ REALCOMPATIBILITY ON} compilador para transformar real de volta para o tipo de seis bytes. As seguintes observações são aplicáveis ??aos tipos reais fundamentais.

  • Real48 é mantido para compatibilidade com versões anteriores. Desde o seu formato de armazenamento não é nativo para a arquitetura do processador Intel, que resulta em um desempenho mais lento do que outros tipos de ponto flutuante.
  • Extensão oferece maior precisão do que outros tipos reais, mas é menos portátil. Tenha cuidado ao usar estendido se você estiver criando arquivos de dados para participação em todas as plataformas.

Observe que o intervalo é maior do que os dígitos significativos. Então você pode ter um número maior, então podem ser armazenados com precisão. Eu recomendaria o arredondamento para os dígitos significativos para impedir que isso aconteça.

Ao usar tipos de ponto flutuante, você deve estar ciente das limitações de precisão sobre os tipos especificados. Um byte 4 IEEE-754 tipo, por exemplo, tem apenas cerca de 7,5 algarismos significativos de precisão. Um oito byte IEEE-754 tipo tem aproximadamente o dobro do número de dígitos significativos. Aparentemente, o tipo real delphi tem uma precisão que se situa em torno de 11 dígitos significativos. O resultado disso é que os dígitos extras de formatação que você especificar são susceptíveis de ser ruído que pode resultar em conversões entre a base 10 valores formatados e base de 2 valores de ponto flutuante.

Primeiro de tudo eu iria tentar ver se eu poderia receber qualquer ajuda de usar Str com argumentos diferentes ou aumentar a precisão dos tipos em seu aplicativo. (Você já tentou usar prolongado?)

Como último recurso, ( Aviso! Solução !! ) eu tentaria salvar representação em cadeia do cliente, juntamente com a representação binária em uma lista ordenada. Antes de escrever de volta um valor de ponto flutuante que veria se já existe um valor correspondente na tabela, cuja representação em cadeia já é conhecido e pode ser usado em seu lugar. A fim de fazer chegar esta rápida pesquisa, você pode classificá-lo sobre o valor numérico e usar a pesquisa binária para encontrar a melhor correspondência.

Dependendo da quantidade de processamento que você precisa fazer, uma alternativa poderia ser a de manter os números em formato BCD para manter a precisão originais.

É difícil responder a isso sem saber o que digitar sua ExportRealValue e ImportRealValue são. Como já foi mencionado, os tipos reais todos têm diferentes precisões.

É importante notar, ao contrário de alguns pensamento, estendido não é sempre maior precisão. Estendida é de 10-20 algarismos significativos onde dupla é 15-16. Como você está tendo problemas em torno da fig décimo sig então está a usar já estendida.

Para obter mais controle sobre a leitura e escrita que você pode converter os números para e de seqüências de si mesmo e gravá-los em um fluxo de arquivo. Pelo menos assim você não precisa se preocupar se readln e writeln são até nenhum bom atrás das costas.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top