# HG changeset patch # User Eldar Insafutdinov # Date 1284500369 -3600 # Node ID ea6325d0edd9f026ad795694177cc82fddd06dd3 # Parent 95b3ed3cddd55c42fa37300312239586a20bb961 + RealExp.toCBuffer diff -r 95b3ed3cddd5 -r ea6325d0edd9 dmd/RealExp.d --- a/dmd/RealExp.d Tue Sep 14 15:25:44 2010 +0200 +++ b/dmd/RealExp.d Tue Sep 14 22:39:29 2010 +0100 @@ -129,7 +129,7 @@ override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { - assert(false); + floatToBuffer(buf, type, value); } override void toMangleBuffer(OutBuffer buf) diff -r 95b3ed3cddd5 -r ea6325d0edd9 dmd/expression/Util.d --- a/dmd/expression/Util.d Tue Sep 14 15:25:44 2010 +0200 +++ b/dmd/expression/Util.d Tue Sep 14 22:39:29 2010 +0100 @@ -71,6 +71,7 @@ import core.stdc.math; import core.stdc.string; +import core.stdc.stdlib; /*********************************** * Utility to build a function call out of this reference and argument. @@ -1771,3 +1772,51 @@ */ memcmp(&x1, &x2, REALSIZE - REALPAD) == 0; } + +void floatToBuffer(OutBuffer buf, Type type, real value) +{ + /* In order to get an exact representation, try converting it + * to decimal then back again. If it matches, use it. + * If it doesn't, fall back to hex, which is + * always exact. + */ + char[25] buffer; + sprintf(buffer.ptr, "%Lg", value); + assert(strlen(buffer.ptr) < buffer.length); +//#ifdef _WIN32 && __DMC__ +// char *save = __locale_decpoint; +// __locale_decpoint = "."; +// real_t r = strtold(buffer, NULL); +// __locale_decpoint = save; +//#else + real r = strtold(buffer.ptr, null); +//#endif + if (r == value) // if exact duplication + buf.writestring(buffer); + else + buf.printf("%La", value); // ensure exact duplication + + if (type) + { + Type t = type.toBasetype(); + switch (t.ty) + { + case Tfloat32: + case Timaginary32: + case Tcomplex32: + buf.writeByte('F'); + break; + + case Tfloat80: + case Timaginary80: + case Tcomplex80: + buf.writeByte('L'); + break; + + default: + break; + } + if (t.isimaginary()) + buf.writeByte('i'); + } +} \ No newline at end of file