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 № 1Há três problemas em potencial na sua pergunta:
A quantidade de precisão exibida. Para controlar a precisão usada, inclua
#include <iomanip>
E usestd::cout << std::setprecision(17);
para definir o número de dígitos a serem usados.Formatação. No caso de querer "12.0" para "12.0", você deve estar ciente de que ".0" não é armazenado em um
float
oudouble
. odouble
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.Precisão. O comum
float
edouble
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 defloat
edouble
, 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.