beste Weg, um ein Double mit voller Genauigkeit in eine Textdatei auszugeben

beste Weg, um ein Double mit voller Genauigkeit in eine Textdatei auszugeben


Ich muss eine vorhandene Textdatei verwenden, um einige sehr genaue Werte zu speichern. Beim Wiedereinlesen müssen die Zahlen im Wesentlichen exakt mit den ursprünglich geschriebenen übereinstimmen. Nun, ein normaler Mensch würde eine Binärdatei verwenden... aus verschiedenen Gründen ist das in diesem Fall nicht möglich.


Also ... hat jemand von Ihnen eine gute Möglichkeit, ein Double als Zeichenfolge zu codieren (abgesehen von der Erhöhung der Genauigkeit). Mein erster Gedanke war, das Double auf ein Zeichen[] zu werfen und die Zeichen auszuschreiben. Ich glaube nicht, dass das funktionieren wird, weil einige der Zeichen nicht sichtbar sind, Töne erzeugen und sogar Zeichenfolgen beenden ('\0'... ich rede mit dir!)


Gedanken?


[Bearbeiten] - Sobald ich herausgefunden habe, welche der vorgeschlagenen Lösungen für mich am besten geeignet ist, werde ich eine als "die" Lösung markieren.


Einige Code-Antworten


#include <iomanip>
#include <sstream>
std::string doubleToText(const double &
d) {
std::stringstream ss;
//ss <<
std::setprecision( std::numeric_limits<double>::digits10+2);
ss <<
std::setprecision( std::numeric_limits<int>::max() );
ss <<
d;
return ss.str();
}
#include <stdlib.h>
double textToDouble(const std::string &
str) {
return strtod( str.c_str(), NULL );
}
#include<iostream>
#include<iomanip>
#include<limits>
#include<cmath>
#include<sstream>
int main(){ std::ostringstream oss;
int prec = std::numeric_limits<double>::digits10+2;
// generally 17 int exponent_digits = std::log10(std::numeric_limits<double>::max_exponent10)+1;
// generally 3 int exponent_sign = 1;
// 1.e-123 int exponent_symbol = 1;
// 'e' 'E' int digits_sign = 1;
int digits_dot = 1;
// 1.2 int division_extra_space = 1;
int width = prec + exponent_digits + digits_sign + exponent_sign + digits_dot + exponent_symbol + division_extra_space;
double original = -0.000013213213e-100/33215.;
oss <<
std::setprecision(prec) <<
std::setw(width) <<
original <<
std::setw(width) <<
original <<
std::setw(width) <<
original <<
'\n';
oss <<
std::setprecision(prec) <<
std::setw(width) <<
1. <<
std::setw(width) <<
2. <<
std::setw(width) <<
-3. <<
'\n';
}
 -3.9780861056751466e-110 -3.9780861056751466e-110 -3.9780861056751466e-110 12
-3
oss <<
std::precision(17) <<
std::setw(25) <<
original <<
...;
    std::istringstream iss(oss.str());
double test;
iss >>
test;
assert(test == original);
int main(int argc, char* argv[]){
union fi {
unsigned int i;
float
f;
} num;
num.f = 1.23f;
printf("%X\n", num.i);
return 0;
}
double d = 0.2512958125912;
std::ostringstream s;
s <<
d;
#include <stdio.h>
#include <math.h>
const int SCALE = 1<<(52/2);
void put( double a ) { FILE* f = fopen( "dump.txt", "wb" );
int sign = (a<0);
if( sign ) a=-a;
int exp2 = 0;
while( a>1 ) a/=2, exp2++;
a*=SCALE;
int m1 = floor(a);
a = (a-m1)*SCALE;
int m2 = floor(a);
fprintf(f, "%i %i %i %i\n", sign, exp2, m1, m2 );
fclose(f);
} double get( void ) { FILE* f = fopen( "dump.txt", "rb" );
double a;
int sign, exp2, m1, m2;
fscanf( f, "%i %i %i %i\n", &sign, &exp2, &m1, &m2 );
fclose(f);
printf( "%i %i %i %i\n", sign, exp2, m1, m2 );
a = m2;
a /= SCALE;
a+= m1;
a /= SCALE;
while( exp2>0 ) a*=2, exp2--;
if( a<0 ) a=-a;
return a;
} int main( void ) { union {
double a;
unsigned b[2];
};
a = 3.1415926;
printf( "%.20lf %08X %08X\n", a, b[0], b[1] );
put( a );
a = get();
printf( "%.20lf %08X %08X\n", a, b[0], b[1] );
}