/ / C ++ convertendo string para float / double sem perda de dados - c ++, string, ponto flutuante

C ++ convertendo string para float / double sem perda de dados - c ++, string, ponto flutuante

Eu estou olhando para converter uma string em um float sem perda de dados; por exemplo, se eu usar istringstream ou :: atof (x.c_str ()), perco dados devido a arredondamentos, eu acho.

Normalmente, isso não é um problema para mim, mas estou usando dados que precisam ser os mesmos da sua leitura. Aqui está um exemplo de um número e para o qual ele é convertido.

-8.000001 -> -8
-0.6257381 -> -0.625738
12.0 -> 12 (drops the .0)

Se alguém pudesse me ajudar eu ficaria muito grato

Graças Matt

Respostas:

4 para resposta № 1

Há três problemas em potencial na sua pergunta:

  1. A quantidade de precisão exibida. Para controlar a precisão usada, inclua #include <iomanip> E use std::cout << std::setprecision(17); para definir o número de dígitos a serem usados.

  2. Formatação. No caso de querer "12.0" para "12.0", você deve estar ciente de que ".0" não é armazenado em um float ou double. o double apenas contém o valor 12; não contémqualquer informação sobre a precisão original ou um intervalo de erro. São exatamente 12 e nada mais. Se você deseja formatá-lo de uma maneira específica, você deve usar os sinalizadores de formato para o fluxo de E / S ou escrever seu próprio código para fazer a formatação.

  3. Precisão. O comum float e double tipos não podem representar exatamente 8.000001 ou 0.6257381. Eles usam binário para representar valores de ponto flutuante e haverá pequenos erros quando os números decimais forem convertidos em binários. Se você tiver usos muito simples de ponto flutuante e estiver trabalhando com significativamente menos dígitos que os limites de float e double, poderá ignorar isso e simplesmente formatar números com seu número limitado de dígitos. Se você exceder casos simples, seria necessário fazer uma análise de erro, o que pode ser bastante complicado.


1 para resposta № 2

Você precisará de um tipo de dados diferente.

Um tipo decimal de ponto flutuante permitirá que vocêarmazene o número exatamente da maneira que desejar. Nesse tipo, os números são armazenados como um par (mantissa, expoente), assim como a notação científica e muito parecido com o ponto flutuante binário IEEE.

Seus exemplos seriam armazenados como

(-8000001, -6)
(-6257381, -7)
(120, -1)

Por exemplo, a norma ISO 11073 para comunicações de dispositivos médicos usa esse formato.

A desvantagem é que a aritmética será bastante lenta, pois todo o hardware aritmético de ponto flutuante foi projetado para funcionar com número usando um expoente com base-2.


0 para resposta № 3

Como regra geral, um float é preciso apenas para 6 números significativos. Portanto, se sua string tiver mais dígitos, você atingirá o limite de precisão.

UMA double não surpreendentemente, lhe dará o dobro dessa precisão; isto é, 12 números significativos.

Vejo Número de dígitos significativos para um tipo de ponto flutuante para mais observações.