Thread overview
Requesting a 2nd review: on the floating-point funcs for conv.d
Apr 16, 2005
David L. Davis
Apr 21, 2005
TechnoZeus
Apr 21, 2005
pragma
Apr 21, 2005
TechnoZeus
Apr 22, 2005
Ben Hinkle
Apr 22, 2005
Ben Hinkle
Apr 23, 2005
David L. Davis
April 16, 2005
Well, I've been pretty busy this past week reworking all of these "from char[]to floating-point" functions (based on advise gotten from Ben Hinkle) that I'd like Walter to include into std.conv. With the sol purpose of filling in the gap of the missing conversion functions for the following datatypes: float, double, real, ifloat, idouble, ireal, cfloat, cdouble, and creal.

If anyone has any interest at all, please at least use an eye-ball or two to look over the code, and better yet, if you have the time, copy and paste this code into dmd v0.121's version of conv.d to test it a bit.

Thanks in advance,
David L.

======================
# //*** Inserted code after //debug=conv within conv.d ***
# private import std.math;    // for fabs(), isnan()
# private import std.string;  // for atof(), split()
# debug( conv ) private import std.stdio; // for writefln() and printf()
# //*** End of insert ***
#
# //*** Inserted code at the end-of-file of conv.d ***
# /***************************************************************
#  * Convert character string to float.
#  * Grammar:
#  * ['+'|'-'] digit {digit}
#  */
# float toFloat(in char[] s)
# {
#     real  r;
#     float f;
#
#     if (!s.length)
#         goto Lerr;
#
#     r = toReal(s);
#     f = cast(float)r;
#
#     if (feq(cast(real)f, r) != 1)
#         if (toString(f) != toString(r))
#             goto Loverflow;
#
#     return cast(float)r;
#
#     Loverflow:
#         conv_overflow(s);
#
#     Lerr:
#         conv_error(s);
#         return 0f;
# }
#
# unittest
# {
#     debug( conv ) writefln( "conv.toFloat.unittest" );
#     float f;
#
#     f = toFloat( "123" );
#     assert( f == 123f );
#     f = toFloat( "+123" );
#     assert( f == +123f );
#     f = toFloat( "-123" );
#     assert( f == -123f );
#     f = toFloat( "123e+2" );
#     assert( f == 123e+2f );
#
#     f = toFloat( "123e-2" );
#     assert( f == 123e-2f );
#     f = toFloat( "123." );
#     assert( f == 123.f );
#     f = toFloat( ".456" );
#     assert( f == .456f );
#
#     //Min and Max values
#     f = toFloat("1.17549e-38");
#     assert(feq(cast(real)f, cast(real)1.17549e-38));
#     assert(feq(cast(real)f, cast(real)float.min));
#     f = toFloat("3.40282e+38");
#     assert(toString(f) == toString(3.40282e+38));
#
#     //nan
#     f = toFloat("nan");
#     assert(toString(f) == toString(float.nan));
# }
#
# /***************************************************************
#  * Convert character string to double.
#  * Grammar:
#  * ['+'|'-'] digit {digit}
#  */
# double toDouble(in char[] s)
# {
#     real   r;
#     double d;
#
#     if (!s.length)
#         goto Lerr;
#
#     r = toReal(s);
#     d = cast(double)r;
#
#     if (feq(r, cast(real)d) != 1)
#         if (toString(d) != toString(r))
#             goto Loverflow;
#
#     return cast(double)r;
#
#     Loverflow:
#         conv_overflow(s);
#
#     Lerr:
#         conv_error(s);
#         return 0;
# }
#
# unittest
# {
#     debug( conv ) writefln( "conv.toDouble.unittest" );
#     double d;
#
#     d = toDouble( "123" );
#     assert( d == 123 );
#     d = toDouble( "+123" );
#     assert( d == +123 );
#     d = toDouble( "-123" );
#     assert( d == -123 );
#     d = toDouble( "123e2" );
#     assert( d == 123e2);
#     d = toDouble( "123e-2" );
#     assert( d == 123e-2 );
#     d = toDouble( "123." );
#     assert( d == 123. );
#     d = toDouble( ".456" );
#     assert( d == .456 );
#     d = toDouble( "1.23456E+2" );
#     assert( d == 1.23456E+2 );
#
#     //Min and Max values
#     d = toDouble("2.22507e-308");
#     assert(feq(cast(real)d, cast(real)2.22507e-308));
#     assert(feq(cast(real)d, cast(real)double.min));
#     d = toDouble("1.79769e+308");
#     assert(toString(d) == toString(1.79769e+308));
#     assert(toString(d) == toString(double.max));
#
#     //nan
#     d = toDouble("nan");
#     assert(toString(d) == toString(double.nan));
# }
#
# /***************************************************************
#  * Convert character string to real.
#  * Grammar:
#  * ['+'|'-'] digit {digit}
#  */
# real toReal(in char[] s)
# {
#     char[] sx;
#     bit    b;
#
#     if (!s.length)
#         goto Lerr;
#
#     b = getFloatStrings(s, sx);
#
#     if (b == 0)
#         goto Lerr;
#
#     return atof(sx);
#
#     Lerr:
#         conv_error(s);
#         return 0.0L;
# }
#
# unittest
# {
#     debug(conv) writefln("conv.toReal.unittest");
#     real r;
#
#     r = toReal("123");
#     assert(r == 123L);
#     r = toReal("+123");
#     assert(r == 123L);
#     r = toReal("-123");
#     assert(r == -123L);
#     r = toReal("123e2");
#     assert(feq(r, 123e2L));
#     r = toReal("123e-2");
#     assert(feq(r, 1.23L));
#     r = toReal("123.");
#     assert(r == 123L);
#     r = toReal(".456");
#     assert(r == .456L);
#
#     r = toReal("1.23456e+2");
#     assert(feq(r,  1.23456e+2L));
#     r = toReal(toString(real.max / 2L));
#     assert(toString(r) == toString(real.max / 2L));
#
#     //Min and Max values
#     r = toReal(toString(real.min));
#     assert(toString(r) == toString(real.min));
#     r = toReal(toString(real.max));
#     assert(toString(r) == toString(real.max));
#
#     //nan
#     r = toReal("nan");
#     assert(toString(r) == toString(real.nan));
# }
#
# /***************************************************************
#  * Convert character string to ifloat.
#  * Grammar:
#  * ['+'|'-'] digit {digit}
#  */
# ifloat toIfloat(in char[] s)
# {
#     real   r;
#     ireal  ir;
#     ifloat ift;
#
#     if (!s.length)
#         goto Lerr;
#
#     r   = toReal(s);
#     ir  = cast(ireal)(r * 1.0i);
#     ift = cast(ifloat)(r * 1.0i);
#
#     if (feq(ir, cast(ireal)ift) != 1)
#         goto Loverflow;
#
#     return ift;
#
#     Loverflow:
#         conv_overflow(s);
#
#     Lerr:
#         conv_error(s);
#         return cast(ifloat)0.0i;
# }
#
# unittest
# {
#     debug(conv) writefln("conv.toIfloat.unittest");
#     ifloat ift;
#
#     ift = toIfloat(toString(ifloat.min));
#
#     assert(toString(ift) == toString(ifloat.min) );
#     assert(feq(cast(ireal)ift, cast(ireal)ifloat.min));
#
#     ift = toIfloat(toString(ifloat.max));
#     assert(toString(ift) == toString(ifloat.max));
#     assert(feq(cast(ireal)ift, cast(ireal)ifloat.max));
#
#     ift = toIfloat(toString(123.45));
#     assert(toString(ift) == toString(123.45i));
#
#     ift = toIfloat(toString(456.77i));
#     assert(toString(ift) == toString(456.77i));
#
#     ift = toIfloat(toString(ifloat.nan));
#     assert(toString(ift.nan) == toString(ifloat.nan));
#     assert(feq(cast(ireal)ift, cast(ireal)ifloat.nan));
# }
#
# /***************************************************************
#  * Convert character string to idouble.
#  * Grammar:
#  * ['+'|'-'] digit {digit}
#  */
# idouble toIdouble(in char[] s)
# {
#     real    r;
#     ireal   ir;
#     idouble id;
#
#     if (!s.length)
#         goto Lerr;
#
#     r  = toReal(s);
#     ir = cast(ireal)(r * 1.0i);
#     id = cast(idouble)(r * 1.0i);
#
#     if (feq(ir, cast(ireal)id) != 1)
#         goto Loverflow;
#
#     return id;
#
#     Loverflow:
#         conv_overflow(s);
#
#     Lerr:
#         conv_error(s);
#         return cast(idouble)0.0i;
# }
#
# unittest
# {
#     debug(conv) writefln("conv.toIdouble.unittest");
#     idouble id;
#
#     id = toIdouble(toString(idouble.min));
#     assert(toString( id ) == toString(idouble.min));
#     assert(feq(cast(ireal)id.re, cast(ireal)idouble.min.re));
#     assert(feq(cast(ireal)id.im, cast(ireal)idouble.min.im));
#
#     id = toIdouble(toString(idouble.max));
#     assert(toString(id) == toString(idouble.max));
#     assert(feq(cast(ireal)id.re, cast(ireal)idouble.max.re));
#     assert(feq(cast(ireal)id.im, cast(ireal)idouble.max.im));
#
#     id = toIdouble(toString("123.45"));
#     assert(id == 123.45i);
#
#     id = toIdouble(toString(idouble.nan));
#     assert(toString(id.nan) == toString(idouble.nan));
# }
#
# /***************************************************************
#  * Convert character string to ireal.
#  * Grammar:
#  * ['+'|'-'] digit {digit}
#  */
# ireal toIreal(in char[] s)
# {
#     real  r;
#     ireal ir;
#
#     if (!s.length)
#         goto Lerr;
#
#     r = toReal(s);
#
#     ir = cast(ireal)(r * 1.0i);
#
#     return ir;
#
#     Lerr:
#         conv_error(s);
#         return cast(ireal)0.0i;
# }
#
# unittest
# {
#     debug(conv) writefln("conv.toIreal.unittest");
#     ireal ir;
#
#     ir = toIreal(toString(ireal.min));
#     assert(toString(ir) == toString(ireal.min));
#     assert(feq(cast(real)ir.re, cast(real)ireal.min.re));
#     assert(feq(cast(real)ir.im, cast(real)ireal.min.im));
#
#     ir = toIreal(toString(ireal.max));
#     assert(toString(ir) == toString(ireal.max));
#     assert(feq(cast(real)ir.re, cast(real)ireal.max.re));
#
#     ir = toIreal(toString("123.45"));
#     assert(feq(cast(real)ir.re, cast(real)123.45i));
#
#     ir = toIreal(toString(ireal.nan));
#     assert(toString(ir.nan) == toString(ireal.nan));
# }
#
# /***************************************************************
#  * Convert character string to cfloat.
#  * Grammar:
#  * ['+'|'-'] digit {digit}
#  */
# cfloat toCfloat(in char[] s)
# {
#     char[] s1;
#     char[] s2;
#     real   r1;
#     real   r2;
#     creal  cr;
#     cfloat cf;
#     bit    b = 0;
#
#     if (!s.length)
#         goto Lerr;
#
#     b = getFloatStrings(s, s1, s2);
#
#     if (b == 0)
#         goto Lerr;
#
#     r1 = atof(s1);
#     r2 = atof(s2);
#
#     cr = cast(creal)cast(creal)r1 + cast(creal)(r2 * 1.0i);
#     cf = cast(cfloat)r1 + cast(cfloat)(r2 * 1.0i);
#
#     if (feq(cr, cast(creal)cf) != 1)
#         goto Loverflow;
#
#     return cf;
#
#     Loverflow:
#         conv_overflow(s);
#
#     Lerr:
#         conv_error(s);
#         return cast(cfloat)0.0e-0+0i;
# }
#
# unittest
# {
#     debug(conv) writefln("conv.toCfloat.unittest");
#     cfloat cf;
#
#     cf = toCfloat(toString(cfloat.min));
#     assert(toString(cf) == toString(cfloat.min));
#
#     cf = toCfloat(toString(cfloat.max));
#     assert(toString(cf) == toString(cfloat.max));
#
#     cf = toCfloat(toString("1.2345e-5+0i"));
#     assert(toString(cf) == toString(1.2345e-5+0i));
#     assert(feq(cf, 1.2345e-5+0i));
# }
#
# /***************************************************************
#  * Convert character string to cdouble.
#  * Grammar:
#  * ['+'|'-'] digit {digit}
#  */
# cdouble toCdouble(in char[] s)
# {
#     char[]  s1;
#     char[]  s2;
#     real    r1;
#     real    r2;
#     creal   cr;
#     cdouble cd;
#     bit     b = 0;
#
#     if (!s.length)
#         goto Lerr;
#
#     b = getFloatStrings(s, s1, s2);
#
#     if (b == 0)
#         goto Lerr;
#
#     r1 = atof(s1);
#     r2 = atof(s2);
#
#     cr = cast(creal)cast(creal)r1 + cast(creal)(r2 * 1.0i);
#     cd = cast(cdouble)r1 + cast(cdouble)(r2 * 1.0i);
#
#     if (feq(cr, cast(creal)cd) != 1)
#         goto Loverflow;
#
#     return cd;
#
#     Loverflow:
#         conv_overflow(s);
#
#     Lerr:
#         conv_error(s);
#         return cast(cdouble)0.0e-0+0i;
# }
#
# unittest
# {
#     debug(conv) writefln("conv.toCdouble.unittest");
#     cdouble cd;
#
#     cd = toCdouble(toString(cdouble.min));
#     assert(toString(cd) == toString(cdouble.min));
#
#     cd = toCdouble(toString(cdouble.max));
#     assert(toString( cd ) == toString(cdouble.max));
#
#     cd = toCdouble(toString("1.2345e-5+0i"));
#     assert(toString( cd ) == toString(1.2345e-5+0i));
#     assert(feq(cd, 1.2345e-5+0i));
# }
#
# /***************************************************************
#  * Convert character string to creal.
#  * Grammar:
#  * ['+'|'-'] digit {digit}
#  */
# creal toCreal(in char[] s)
# {
#     char[] s1;
#     char[] s2;
#     real   r1;
#     real   r2;
#     creal  cr;
#     bit    b = 0;
#
#     if (!s.length)
#         goto Lerr;
#
#     b = getFloatStrings(s, s1, s2);
#
#     if (b == 0)
#         goto Lerr;
#
#     r1 = atof(s1);
#     r2 = atof(s2);
#
#     if (r2 != 0.0)
#         cr = cast(creal)(r1 + (r2 * 1.0i));
#     else
#         cr = cast(creal)(r1 + cast(creal)0.0i);
#
#     return cr;
#
#     Lerr:
#         conv_error(s);
#         return cast(creal)0.0e-0+0i;
# }
#
# unittest
# {
#     debug(conv) writefln("conv.toCreal.unittest");
#     creal cr;
#
#     cr = toCreal(toString(creal.min));
#     assert(toString(cr) == toString(creal.min));
#     assert(feq(cr, creal.min));
#
#     cr = toCreal(toString(creal.max));
#     assert(toString(cr) == toString(creal.max));
#     assert(feq(cr, creal.max));
#
#     cr = toCreal(toString("1.2345e-5+0i"));
#     assert(toString(cr) == toString(1.2345e-5+0i));
#     assert(feq(cr, 1.2345e-5+0i));
#
#     cr = toCreal(toString("0.0e-0+0i"));
#     assert(toString(cr) == toString(0.0e-0+0i));
#     assert(cr == 0.0e-0+0i);
#     assert(feq(cr, 0.0e-0+0i));
#
#     cr = toCreal("123");
#     assert(cr == 123);
#
#     cr = toCreal("+5");
#     assert(cr == 5);
#
#     cr = toCreal("-78");
#     assert(cr == -78);
# }
#
# /***************************************************************
#  * Validates a character string for the following datatypes:
#  * float, double, real, ifloat, idouble, and ireal
#  * Grammar:
#  * ['+'|'-'] string floating-point digit {digit}
#  * also allows ".", "i", "f", "L", "e" within the string
#  */
# private bit getFloatStrings(in char[] s, out char[] s1)
# {
#      char[] s2 = "0";
#
#      return getFloatStrings(s, s1, s2);
# }
#
# /***************************************************************
#  * Validates and modified a character string for the following datatype:
#  * cfloat, cdouble, and creal
#  * Grammar:
#  * ['+'|'-'] string floating-point digit {digit}
#  * also allows ".", "i", "f", "L", "e" within the string
#  *
#  * s1 returns the first number from the string
#  * s2 returns the second (or zeroed out) number from the string
#  */
# private bit getFloatStrings(in char[] s, out char[] s1, out char[] s2)
# {
#     char[][] a;
#     char[]   w   = s.dup;
#     int      len = w.length;
#
#     if (!len)
#         goto Lerr;
#
#     // Returns: 0 = error, 1 = ok to use
#     bit isFloatingValue(in char[] s)
#     {
#         char c;
#         int  len = s.length;
#         int  periods = 0;
#
#         for (int i = 0; i < len; i++)
#         {
#             c = s[i];
#
#             // Set the following characters to lowercase.
#             if (c == 'E' || c == 'I' || c == 'F')
#             {
#                 s[i] = c + (cast(char)'a' - 'A');
#                 c = s[i];
#             }
#
#             if (c >= '0' && c <= '9')
#                 continue;
#             else if (((c == '-') && (i != len - 1)) && len != 1)
#                 continue;
#             else if (((c == '+') && (i != len - 1)) && len != 1)
#                 continue;
#             else if (((c == 'e') && (i != len - 1)) && len != 1)
#                 continue;
#             else if (c == '.' && periods <= 2 && len != 1)
#             {
#                 periods++;
#                 continue;
#             }
#             else if (((c == 'i') && (i == len - 1)) && len != 1)
#                 continue;
#             else if (((c == 'f') && (i == len - 1)) && len != 1 )
#                 continue;
#             else if (((c == 'L') && (i == len - 1)) && len != 1)
#                 continue;
#             else
#                 return 0;
#         }
#
#         return 1;
#     }
#
#     // When "nan" or "nani" just return them.
#     if (w == "nan" || w == "nani")
#     {
#         s1 = w;
#         s2 = "0e+0";
#         return 1;
#     }
#
#     // Split the original string out into two strings.
#     for (int i = 1; i < len; i++)
#         if ((w[i - 1] != 'e' && w[i - 1] != 'E') && w[i] == '+')
#         {
#             w[i] = '^';
#             a = split(w, "^");
#             break;
#         }
#
#     // Handle the case when there's only a single value
#     //  to work with, and set the other string to zero.
#     if (a.length == 0)
#         a = split(w ~ "^0e+0", "^");
#
#     // Check the first string.
#     if (isFloatingValue(a[0]))
#         s1 = a[0].dup;
#     else
#         goto Lerr;
#
#     // Check the second string.
#     if (isFloatingValue(a[1]))
#         s2 = a[1].dup;
#     else
#         goto Lerr;
#
#     // String is good enough to pass
#     // into the atof() function. :)
#     return 1;
#
#     Lerr:
#         // Display the original string in the error message.
#         conv_error("\"" ~ s ~ "\"");
#         return 0;
# }
#
# unittest
# {
#     debug(conv) writefln("conv.getFloatStrings.unittest");
#     char[] s1;
#     char[] s2;
#     bit    b = 0;
#
#     static char[][] errors =
#     [
#         "",
#         "-",
#         "+",
#         "-+",
#         " ",
#         " 0",
#         "0 ",
#         "- 0",
#         "1-",
#         "xx",
#         "123h",
#     ];
#
#     for (int j = 0; j < errors.length; j++)
#     {
#         b = 1;
#         try
#         {
#             b = getFloatStrings(errors[j], s1, s2);
#         }
#         catch (Error e)
#         {
#             debug(conv) e.print();
#             b = 0;
#         }
#         assert(b == 0);
#     }
# }
#
# /****************************************
#  * Main function tp compare reals with given precision
#  */
# private bit feq(in real rx, in real ry, in real precision)
# {
#     if (rx == ry)
#         return 1;
#
#     if (isnan(rx))
#         return cast(bit)isnan(ry);
#
#     if (isnan(ry))
#         return 0;
#
#     return cast(bit)(fabs(rx - ry) <= precision);
# }
#
# /****************************************
#  * (Note: Copied here from std.math's mfeq() function for unittesting)
#  * Simple function to compare two floating point values
#  * to a specified precision.
#  * Returns:
#  *  1   match
#  *  0   nomatch
#  */
#  private bit feq(in real r1, in real r2)
# {
#     if (r1 == r2)
#         return 1;
#
#     if (isnan(r1))
#         return cast(bit)isnan(r2);
#
#     if (isnan(r2))
#         return 0;
#
#     return cast(bit)(feq(r1, r2, 0.000001L));
# }
#
# /****************************************
#  * compare ireals with given precision
#  */
# private bit feq(in ireal r1, in ireal r2)
# {
#     real rx = cast(real)r1;
#     real ry = cast(real)r2;
#
#     if (rx == ry)
#         return 1;
#
#     if (isnan(rx))
#         return cast(bit)isnan(ry);
#
#     if (isnan(ry))
#         return 0;
#
#     return feq(rx, ry, 0.000001L);
# }
#
# /****************************************
#  * compare creals with given precision
#  */
# private bit feq(in creal r1, in creal r2)
# {
#     real r1a = fabs(cast(real)r1.re - cast(real)r2.re);
#     real r2b = fabs(cast(real)r1.im - cast(real)r2.im);
#
#     if ((cast(real)r1.re == cast(real)r2.re) &&
#         (cast(real)r1.im == cast(real)r2.im))
#         return 1;
#
#     if (isnan(r1a))
#         return cast(bit)isnan(r2b);
#
#     if (isnan(r2b))
#         return 0;
#
#     return feq(r1a, r2b, 0.000001L);
# }
# //*** End of insert ***



-------------------------------------------------------------------
"Dare to reach for the Stars...Dare to Dream, Build, and Achieve!"
-------------------------------------------------------------------

MKoD: http://spottedtiger.tripod.com/D_Language/D_Main_XP.html
April 21, 2005
Got a link to a listing without the "#" character at the start of each line?  :)

TZ

"David L. Davis" <SpottedTiger@yahoo.com> wrote in message news:d3s8pt$j68$1@digitaldaemon.com...
> Well, I've been pretty busy this past week reworking all of these "from char[]to floating-point" functions (based on advise gotten from Ben Hinkle) that I'd like Walter to include into std.conv. With the sol purpose of filling in the gap of the missing conversion functions for the following datatypes: float, double, real, ifloat, idouble, ireal, cfloat, cdouble, and creal.
>
> If anyone has any interest at all, please at least use an eye-ball or two to look over the code, and better yet, if you have the time, copy and paste this code into dmd v0.121's version of conv.d to test it a bit.
>
> Thanks in advance,
> David L.
>
> ======================
> # //*** Inserted code after //debug=conv within conv.d ***
> # private import std.math;    // for fabs(), isnan()
> # private import std.string;  // for atof(), split()
> # debug( conv ) private import std.stdio; // for writefln() and printf()
> # //*** End of insert ***
> #
> # //*** Inserted code at the end-of-file of conv.d ***
> # /***************************************************************
> #  * Convert character string to float.
> #  * Grammar:
> #  * ['+'|'-'] digit {digit}
> #  */
> # float toFloat(in char[] s)
> # {
> #     real  r;
> #     float f;
> #
> #     if (!s.length)
> #         goto Lerr;
> #
> #     r = toReal(s);
> #     f = cast(float)r;
> #
> #     if (feq(cast(real)f, r) != 1)
> #         if (toString(f) != toString(r))
> #             goto Loverflow;
> #
> #     return cast(float)r;
> #
> #     Loverflow:
> #         conv_overflow(s);
> #
> #     Lerr:
> #         conv_error(s);
> #         return 0f;
> # }
> #
> # unittest
> # {
> #     debug( conv ) writefln( "conv.toFloat.unittest" );
> #     float f;
> #
> #     f = toFloat( "123" );
> #     assert( f == 123f );
> #     f = toFloat( "+123" );
> #     assert( f == +123f );
> #     f = toFloat( "-123" );
> #     assert( f == -123f );
> #     f = toFloat( "123e+2" );
> #     assert( f == 123e+2f );
> #
> #     f = toFloat( "123e-2" );
> #     assert( f == 123e-2f );
> #     f = toFloat( "123." );
> #     assert( f == 123.f );
> #     f = toFloat( ".456" );
> #     assert( f == .456f );
> #
> #     //Min and Max values
> #     f = toFloat("1.17549e-38");
> #     assert(feq(cast(real)f, cast(real)1.17549e-38));
> #     assert(feq(cast(real)f, cast(real)float.min));
> #     f = toFloat("3.40282e+38");
> #     assert(toString(f) == toString(3.40282e+38));
> #
> #     //nan
> #     f = toFloat("nan");
> #     assert(toString(f) == toString(float.nan));
> # }
> #
> # /***************************************************************
> #  * Convert character string to double.
> #  * Grammar:
> #  * ['+'|'-'] digit {digit}
> #  */
> # double toDouble(in char[] s)
> # {
> #     real   r;
> #     double d;
> #
> #     if (!s.length)
> #         goto Lerr;
> #
> #     r = toReal(s);
> #     d = cast(double)r;
> #
> #     if (feq(r, cast(real)d) != 1)
> #         if (toString(d) != toString(r))
> #             goto Loverflow;
> #
> #     return cast(double)r;
> #
> #     Loverflow:
> #         conv_overflow(s);
> #
> #     Lerr:
> #         conv_error(s);
> #         return 0;
> # }
> #
> # unittest
> # {
> #     debug( conv ) writefln( "conv.toDouble.unittest" );
> #     double d;
> #
> #     d = toDouble( "123" );
> #     assert( d == 123 );
> #     d = toDouble( "+123" );
> #     assert( d == +123 );
> #     d = toDouble( "-123" );
> #     assert( d == -123 );
> #     d = toDouble( "123e2" );
> #     assert( d == 123e2);
> #     d = toDouble( "123e-2" );
> #     assert( d == 123e-2 );
> #     d = toDouble( "123." );
> #     assert( d == 123. );
> #     d = toDouble( ".456" );
> #     assert( d == .456 );
> #     d = toDouble( "1.23456E+2" );
> #     assert( d == 1.23456E+2 );
> #
> #     //Min and Max values
> #     d = toDouble("2.22507e-308");
> #     assert(feq(cast(real)d, cast(real)2.22507e-308));
> #     assert(feq(cast(real)d, cast(real)double.min));
> #     d = toDouble("1.79769e+308");
> #     assert(toString(d) == toString(1.79769e+308));
> #     assert(toString(d) == toString(double.max));
> #
> #     //nan
> #     d = toDouble("nan");
> #     assert(toString(d) == toString(double.nan));
> # }
> #
> # /***************************************************************
> #  * Convert character string to real.
> #  * Grammar:
> #  * ['+'|'-'] digit {digit}
> #  */
> # real toReal(in char[] s)
> # {
> #     char[] sx;
> #     bit    b;
> #
> #     if (!s.length)
> #         goto Lerr;
> #
> #     b = getFloatStrings(s, sx);
> #
> #     if (b == 0)
> #         goto Lerr;
> #
> #     return atof(sx);
> #
> #     Lerr:
> #         conv_error(s);
> #         return 0.0L;
> # }
> #
> # unittest
> # {
> #     debug(conv) writefln("conv.toReal.unittest");
> #     real r;
> #
> #     r = toReal("123");
> #     assert(r == 123L);
> #     r = toReal("+123");
> #     assert(r == 123L);
> #     r = toReal("-123");
> #     assert(r == -123L);
> #     r = toReal("123e2");
> #     assert(feq(r, 123e2L));
> #     r = toReal("123e-2");
> #     assert(feq(r, 1.23L));
> #     r = toReal("123.");
> #     assert(r == 123L);
> #     r = toReal(".456");
> #     assert(r == .456L);
> #
> #     r = toReal("1.23456e+2");
> #     assert(feq(r,  1.23456e+2L));
> #     r = toReal(toString(real.max / 2L));
> #     assert(toString(r) == toString(real.max / 2L));
> #
> #     //Min and Max values
> #     r = toReal(toString(real.min));
> #     assert(toString(r) == toString(real.min));
> #     r = toReal(toString(real.max));
> #     assert(toString(r) == toString(real.max));
> #
> #     //nan
> #     r = toReal("nan");
> #     assert(toString(r) == toString(real.nan));
> # }
> #
> # /***************************************************************
> #  * Convert character string to ifloat.
> #  * Grammar:
> #  * ['+'|'-'] digit {digit}
> #  */
> # ifloat toIfloat(in char[] s)
> # {
> #     real   r;
> #     ireal  ir;
> #     ifloat ift;
> #
> #     if (!s.length)
> #         goto Lerr;
> #
> #     r   = toReal(s);
> #     ir  = cast(ireal)(r * 1.0i);
> #     ift = cast(ifloat)(r * 1.0i);
> #
> #     if (feq(ir, cast(ireal)ift) != 1)
> #         goto Loverflow;
> #
> #     return ift;
> #
> #     Loverflow:
> #         conv_overflow(s);
> #
> #     Lerr:
> #         conv_error(s);
> #         return cast(ifloat)0.0i;
> # }
> #
> # unittest
> # {
> #     debug(conv) writefln("conv.toIfloat.unittest");
> #     ifloat ift;
> #
> #     ift = toIfloat(toString(ifloat.min));
> #
> #     assert(toString(ift) == toString(ifloat.min) );
> #     assert(feq(cast(ireal)ift, cast(ireal)ifloat.min));
> #
> #     ift = toIfloat(toString(ifloat.max));
> #     assert(toString(ift) == toString(ifloat.max));
> #     assert(feq(cast(ireal)ift, cast(ireal)ifloat.max));
> #
> #     ift = toIfloat(toString(123.45));
> #     assert(toString(ift) == toString(123.45i));
> #
> #     ift = toIfloat(toString(456.77i));
> #     assert(toString(ift) == toString(456.77i));
> #
> #     ift = toIfloat(toString(ifloat.nan));
> #     assert(toString(ift.nan) == toString(ifloat.nan));
> #     assert(feq(cast(ireal)ift, cast(ireal)ifloat.nan));
> # }
> #
> # /***************************************************************
> #  * Convert character string to idouble.
> #  * Grammar:
> #  * ['+'|'-'] digit {digit}
> #  */
> # idouble toIdouble(in char[] s)
> # {
> #     real    r;
> #     ireal   ir;
> #     idouble id;
> #
> #     if (!s.length)
> #         goto Lerr;
> #
> #     r  = toReal(s);
> #     ir = cast(ireal)(r * 1.0i);
> #     id = cast(idouble)(r * 1.0i);
> #
> #     if (feq(ir, cast(ireal)id) != 1)
> #         goto Loverflow;
> #
> #     return id;
> #
> #     Loverflow:
> #         conv_overflow(s);
> #
> #     Lerr:
> #         conv_error(s);
> #         return cast(idouble)0.0i;
> # }
> #
> # unittest
> # {
> #     debug(conv) writefln("conv.toIdouble.unittest");
> #     idouble id;
> #
> #     id = toIdouble(toString(idouble.min));
> #     assert(toString( id ) == toString(idouble.min));
> #     assert(feq(cast(ireal)id.re, cast(ireal)idouble.min.re));
> #     assert(feq(cast(ireal)id.im, cast(ireal)idouble.min.im));
> #
> #     id = toIdouble(toString(idouble.max));
> #     assert(toString(id) == toString(idouble.max));
> #     assert(feq(cast(ireal)id.re, cast(ireal)idouble.max.re));
> #     assert(feq(cast(ireal)id.im, cast(ireal)idouble.max.im));
> #
> #     id = toIdouble(toString("123.45"));
> #     assert(id == 123.45i);
> #
> #     id = toIdouble(toString(idouble.nan));
> #     assert(toString(id.nan) == toString(idouble.nan));
> # }
> #
> # /***************************************************************
> #  * Convert character string to ireal.
> #  * Grammar:
> #  * ['+'|'-'] digit {digit}
> #  */
> # ireal toIreal(in char[] s)
> # {
> #     real  r;
> #     ireal ir;
> #
> #     if (!s.length)
> #         goto Lerr;
> #
> #     r = toReal(s);
> #
> #     ir = cast(ireal)(r * 1.0i);
> #
> #     return ir;
> #
> #     Lerr:
> #         conv_error(s);
> #         return cast(ireal)0.0i;
> # }
> #
> # unittest
> # {
> #     debug(conv) writefln("conv.toIreal.unittest");
> #     ireal ir;
> #
> #     ir = toIreal(toString(ireal.min));
> #     assert(toString(ir) == toString(ireal.min));
> #     assert(feq(cast(real)ir.re, cast(real)ireal.min.re));
> #     assert(feq(cast(real)ir.im, cast(real)ireal.min.im));
> #
> #     ir = toIreal(toString(ireal.max));
> #     assert(toString(ir) == toString(ireal.max));
> #     assert(feq(cast(real)ir.re, cast(real)ireal.max.re));
> #
> #     ir = toIreal(toString("123.45"));
> #     assert(feq(cast(real)ir.re, cast(real)123.45i));
> #
> #     ir = toIreal(toString(ireal.nan));
> #     assert(toString(ir.nan) == toString(ireal.nan));
> # }
> #
> # /***************************************************************
> #  * Convert character string to cfloat.
> #  * Grammar:
> #  * ['+'|'-'] digit {digit}
> #  */
> # cfloat toCfloat(in char[] s)
> # {
> #     char[] s1;
> #     char[] s2;
> #     real   r1;
> #     real   r2;
> #     creal  cr;
> #     cfloat cf;
> #     bit    b = 0;
> #
> #     if (!s.length)
> #         goto Lerr;
> #
> #     b = getFloatStrings(s, s1, s2);
> #
> #     if (b == 0)
> #         goto Lerr;
> #
> #     r1 = atof(s1);
> #     r2 = atof(s2);
> #
> #     cr = cast(creal)cast(creal)r1 + cast(creal)(r2 * 1.0i);
> #     cf = cast(cfloat)r1 + cast(cfloat)(r2 * 1.0i);
> #
> #     if (feq(cr, cast(creal)cf) != 1)
> #         goto Loverflow;
> #
> #     return cf;
> #
> #     Loverflow:
> #         conv_overflow(s);
> #
> #     Lerr:
> #         conv_error(s);
> #         return cast(cfloat)0.0e-0+0i;
> # }
> #
> # unittest
> # {
> #     debug(conv) writefln("conv.toCfloat.unittest");
> #     cfloat cf;
> #
> #     cf = toCfloat(toString(cfloat.min));
> #     assert(toString(cf) == toString(cfloat.min));
> #
> #     cf = toCfloat(toString(cfloat.max));
> #     assert(toString(cf) == toString(cfloat.max));
> #
> #     cf = toCfloat(toString("1.2345e-5+0i"));
> #     assert(toString(cf) == toString(1.2345e-5+0i));
> #     assert(feq(cf, 1.2345e-5+0i));
> # }
> #
> # /***************************************************************
> #  * Convert character string to cdouble.
> #  * Grammar:
> #  * ['+'|'-'] digit {digit}
> #  */
> # cdouble toCdouble(in char[] s)
> # {
> #     char[]  s1;
> #     char[]  s2;
> #     real    r1;
> #     real    r2;
> #     creal   cr;
> #     cdouble cd;
> #     bit     b = 0;
> #
> #     if (!s.length)
> #         goto Lerr;
> #
> #     b = getFloatStrings(s, s1, s2);
> #
> #     if (b == 0)
> #         goto Lerr;
> #
> #     r1 = atof(s1);
> #     r2 = atof(s2);
> #
> #     cr = cast(creal)cast(creal)r1 + cast(creal)(r2 * 1.0i);
> #     cd = cast(cdouble)r1 + cast(cdouble)(r2 * 1.0i);
> #
> #     if (feq(cr, cast(creal)cd) != 1)
> #         goto Loverflow;
> #
> #     return cd;
> #
> #     Loverflow:
> #         conv_overflow(s);
> #
> #     Lerr:
> #         conv_error(s);
> #         return cast(cdouble)0.0e-0+0i;
> # }
> #
> # unittest
> # {
> #     debug(conv) writefln("conv.toCdouble.unittest");
> #     cdouble cd;
> #
> #     cd = toCdouble(toString(cdouble.min));
> #     assert(toString(cd) == toString(cdouble.min));
> #
> #     cd = toCdouble(toString(cdouble.max));
> #     assert(toString( cd ) == toString(cdouble.max));
> #
> #     cd = toCdouble(toString("1.2345e-5+0i"));
> #     assert(toString( cd ) == toString(1.2345e-5+0i));
> #     assert(feq(cd, 1.2345e-5+0i));
> # }
> #
> # /***************************************************************
> #  * Convert character string to creal.
> #  * Grammar:
> #  * ['+'|'-'] digit {digit}
> #  */
> # creal toCreal(in char[] s)
> # {
> #     char[] s1;
> #     char[] s2;
> #     real   r1;
> #     real   r2;
> #     creal  cr;
> #     bit    b = 0;
> #
> #     if (!s.length)
> #         goto Lerr;
> #
> #     b = getFloatStrings(s, s1, s2);
> #
> #     if (b == 0)
> #         goto Lerr;
> #
> #     r1 = atof(s1);
> #     r2 = atof(s2);
> #
> #     if (r2 != 0.0)
> #         cr = cast(creal)(r1 + (r2 * 1.0i));
> #     else
> #         cr = cast(creal)(r1 + cast(creal)0.0i);
> #
> #     return cr;
> #
> #     Lerr:
> #         conv_error(s);
> #         return cast(creal)0.0e-0+0i;
> # }
> #
> # unittest
> # {
> #     debug(conv) writefln("conv.toCreal.unittest");
> #     creal cr;
> #
> #     cr = toCreal(toString(creal.min));
> #     assert(toString(cr) == toString(creal.min));
> #     assert(feq(cr, creal.min));
> #
> #     cr = toCreal(toString(creal.max));
> #     assert(toString(cr) == toString(creal.max));
> #     assert(feq(cr, creal.max));
> #
> #     cr = toCreal(toString("1.2345e-5+0i"));
> #     assert(toString(cr) == toString(1.2345e-5+0i));
> #     assert(feq(cr, 1.2345e-5+0i));
> #
> #     cr = toCreal(toString("0.0e-0+0i"));
> #     assert(toString(cr) == toString(0.0e-0+0i));
> #     assert(cr == 0.0e-0+0i);
> #     assert(feq(cr, 0.0e-0+0i));
> #
> #     cr = toCreal("123");
> #     assert(cr == 123);
> #
> #     cr = toCreal("+5");
> #     assert(cr == 5);
> #
> #     cr = toCreal("-78");
> #     assert(cr == -78);
> # }
> #
> # /***************************************************************
> #  * Validates a character string for the following datatypes:
> #  * float, double, real, ifloat, idouble, and ireal
> #  * Grammar:
> #  * ['+'|'-'] string floating-point digit {digit}
> #  * also allows ".", "i", "f", "L", "e" within the string
> #  */
> # private bit getFloatStrings(in char[] s, out char[] s1)
> # {
> #      char[] s2 = "0";
> #
> #      return getFloatStrings(s, s1, s2);
> # }
> #
> # /***************************************************************
> #  * Validates and modified a character string for the following datatype:
> #  * cfloat, cdouble, and creal
> #  * Grammar:
> #  * ['+'|'-'] string floating-point digit {digit}
> #  * also allows ".", "i", "f", "L", "e" within the string
> #  *
> #  * s1 returns the first number from the string
> #  * s2 returns the second (or zeroed out) number from the string
> #  */
> # private bit getFloatStrings(in char[] s, out char[] s1, out char[] s2)
> # {
> #     char[][] a;
> #     char[]   w   = s.dup;
> #     int      len = w.length;
> #
> #     if (!len)
> #         goto Lerr;
> #
> #     // Returns: 0 = error, 1 = ok to use
> #     bit isFloatingValue(in char[] s)
> #     {
> #         char c;
> #         int  len = s.length;
> #         int  periods = 0;
> #
> #         for (int i = 0; i < len; i++)
> #         {
> #             c = s[i];
> #
> #             // Set the following characters to lowercase.
> #             if (c == 'E' || c == 'I' || c == 'F')
> #             {
> #                 s[i] = c + (cast(char)'a' - 'A');
> #                 c = s[i];
> #             }
> #
> #             if (c >= '0' && c <= '9')
> #                 continue;
> #             else if (((c == '-') && (i != len - 1)) && len != 1)
> #                 continue;
> #             else if (((c == '+') && (i != len - 1)) && len != 1)
> #                 continue;
> #             else if (((c == 'e') && (i != len - 1)) && len != 1)
> #                 continue;
> #             else if (c == '.' && periods <= 2 && len != 1)
> #             {
> #                 periods++;
> #                 continue;
> #             }
> #             else if (((c == 'i') && (i == len - 1)) && len != 1)
> #                 continue;
> #             else if (((c == 'f') && (i == len - 1)) && len != 1 )
> #                 continue;
> #             else if (((c == 'L') && (i == len - 1)) && len != 1)
> #                 continue;
> #             else
> #                 return 0;
> #         }
> #
> #         return 1;
> #     }
> #
> #     // When "nan" or "nani" just return them.
> #     if (w == "nan" || w == "nani")
> #     {
> #         s1 = w;
> #         s2 = "0e+0";
> #         return 1;
> #     }
> #
> #     // Split the original string out into two strings.
> #     for (int i = 1; i < len; i++)
> #         if ((w[i - 1] != 'e' && w[i - 1] != 'E') && w[i] == '+')
> #         {
> #             w[i] = '^';
> #             a = split(w, "^");
> #             break;
> #         }
> #
> #     // Handle the case when there's only a single value
> #     //  to work with, and set the other string to zero.
> #     if (a.length == 0)
> #         a = split(w ~ "^0e+0", "^");
> #
> #     // Check the first string.
> #     if (isFloatingValue(a[0]))
> #         s1 = a[0].dup;
> #     else
> #         goto Lerr;
> #
> #     // Check the second string.
> #     if (isFloatingValue(a[1]))
> #         s2 = a[1].dup;
> #     else
> #         goto Lerr;
> #
> #     // String is good enough to pass
> #     // into the atof() function. :)
> #     return 1;
> #
> #     Lerr:
> #         // Display the original string in the error message.
> #         conv_error("\"" ~ s ~ "\"");
> #         return 0;
> # }
> #
> # unittest
> # {
> #     debug(conv) writefln("conv.getFloatStrings.unittest");
> #     char[] s1;
> #     char[] s2;
> #     bit    b = 0;
> #
> #     static char[][] errors =
> #     [
> #         "",
> #         "-",
> #         "+",
> #         "-+",
> #         " ",
> #         " 0",
> #         "0 ",
> #         "- 0",
> #         "1-",
> #         "xx",
> #         "123h",
> #     ];
> #
> #     for (int j = 0; j < errors.length; j++)
> #     {
> #         b = 1;
> #         try
> #         {
> #             b = getFloatStrings(errors[j], s1, s2);
> #         }
> #         catch (Error e)
> #         {
> #             debug(conv) e.print();
> #             b = 0;
> #         }
> #         assert(b == 0);
> #     }
> # }
> #
> # /****************************************
> #  * Main function tp compare reals with given precision
> #  */
> # private bit feq(in real rx, in real ry, in real precision)
> # {
> #     if (rx == ry)
> #         return 1;
> #
> #     if (isnan(rx))
> #         return cast(bit)isnan(ry);
> #
> #     if (isnan(ry))
> #         return 0;
> #
> #     return cast(bit)(fabs(rx - ry) <= precision);
> # }
> #
> # /****************************************
> #  * (Note: Copied here from std.math's mfeq() function for unittesting)
> #  * Simple function to compare two floating point values
> #  * to a specified precision.
> #  * Returns:
> #  *  1   match
> #  *  0   nomatch
> #  */
> #  private bit feq(in real r1, in real r2)
> # {
> #     if (r1 == r2)
> #         return 1;
> #
> #     if (isnan(r1))
> #         return cast(bit)isnan(r2);
> #
> #     if (isnan(r2))
> #         return 0;
> #
> #     return cast(bit)(feq(r1, r2, 0.000001L));
> # }
> #
> # /****************************************
> #  * compare ireals with given precision
> #  */
> # private bit feq(in ireal r1, in ireal r2)
> # {
> #     real rx = cast(real)r1;
> #     real ry = cast(real)r2;
> #
> #     if (rx == ry)
> #         return 1;
> #
> #     if (isnan(rx))
> #         return cast(bit)isnan(ry);
> #
> #     if (isnan(ry))
> #         return 0;
> #
> #     return feq(rx, ry, 0.000001L);
> # }
> #
> # /****************************************
> #  * compare creals with given precision
> #  */
> # private bit feq(in creal r1, in creal r2)
> # {
> #     real r1a = fabs(cast(real)r1.re - cast(real)r2.re);
> #     real r2b = fabs(cast(real)r1.im - cast(real)r2.im);
> #
> #     if ((cast(real)r1.re == cast(real)r2.re) &&
> #         (cast(real)r1.im == cast(real)r2.im))
> #         return 1;
> #
> #     if (isnan(r1a))
> #         return cast(bit)isnan(r2b);
> #
> #     if (isnan(r2b))
> #         return 0;
> #
> #     return feq(r1a, r2b, 0.000001L);
> # }
> # //*** End of insert ***
>
>
>
> -------------------------------------------------------------------
> "Dare to reach for the Stars...Dare to Dream, Build, and Achieve!"
> -------------------------------------------------------------------
>
> MKoD: http://spottedtiger.tripod.com/D_Language/D_Main_XP.html


April 21, 2005
In article <d48dvl$5l9$1@digitaldaemon.com>, TechnoZeus says...
>
>Got a link to a listing without the "#" character at the start of each line?  :)
>

No need, just use the following util to process the file.

// strip.d
// useage: strip.exe <infile> <outfile>
import std.file;
import std.regexp;

void main(char[][] args){
if(args.length != 3) return;
std.file.write(args[2],std.regexp.sub(cast(char[])std.file.read(args[1]),"^#","","gmi"));
}

- EricAnderton at yahoo
April 21, 2005
Thanks.  :)

TZ

"pragma" <pragma_member@pathlink.com> wrote in message news:d48gbv$7r4$1@digitaldaemon.com...
> In article <d48dvl$5l9$1@digitaldaemon.com>, TechnoZeus says...
> >
> >Got a link to a listing without the "#" character at the start of each line?  :)
> >
>
> No need, just use the following util to process the file.
>
> // strip.d
> // useage: strip.exe <infile> <outfile>
> import std.file;
> import std.regexp;
>
> void main(char[][] args){
> if(args.length != 3) return;
> std.file.write(args[2],std.regexp.sub(cast(char[])std.file.read(args[1]),"^#","","gmi"));
> }
>
> - EricAnderton at yahoo


April 22, 2005
It's looking better and better. I hope Walter eventually takes it. My
comments from going over it with a fine-tooth comb:
1) when returning or testing bit values use true/false instead of 0/1 (or
just test the value without having ==true at all).

2) in getFloatStrings if a copy of the strings is really needed try to use a buffer on the stack instead of always dup'ing. Converting a string to a numeric value shouldn't generate garbage unless really needed. For example the calling functions can have a buffer it passes to getFloatString and if it isn't long enough getFloatStrings can reallocate. Also I wouldn't dup the return strings - just let them live as slices if at all possible.

3) in the overflow checking can things like
   if (!feq(cast(real)f,r)) ... overflow...
be replaced with
   if (r > float.max) ... overflow ...
I'm not exactly sure what the original test is catching as overflow - can
you explain it in words?

4) can the code cast(ireal)r*1.0i) be replaced with cast(ireal)r or maybe cast(ireal)cast(real)r if that doesn't work?

5) in a few of the toCDouble and friends there are two cast(creal) in a row. Are they needed?

thanks for taking a crack at this!
-Ben

"David L. Davis" <SpottedTiger@yahoo.com> wrote in message news:d3s8pt$j68$1@digitaldaemon.com...
> Well, I've been pretty busy this past week reworking all of these "from
> char[]to
> floating-point" functions (based on advise gotten from Ben Hinkle) that
> I'd like
> Walter to include into std.conv. With the sol purpose of filling in the
> gap of
> the missing conversion functions for the following datatypes: float,
> double,
> real, ifloat, idouble, ireal, cfloat, cdouble, and creal.
>
> If anyone has any interest at all, please at least use an eye-ball or two
> to
> look over the code, and better yet, if you have the time, copy and paste
> this
> code into dmd v0.121's version of conv.d to test it a bit.
>
> Thanks in advance,
> David L.
>
> ======================
> # //*** Inserted code after //debug=conv within conv.d ***
> # private import std.math;    // for fabs(), isnan()
> # private import std.string;  // for atof(), split()
> # debug( conv ) private import std.stdio; // for writefln() and printf()
> # //*** End of insert ***
> #
> # //*** Inserted code at the end-of-file of conv.d ***
> # /***************************************************************
> #  * Convert character string to float.
> #  * Grammar:
> #  * ['+'|'-'] digit {digit}
> #  */
> # float toFloat(in char[] s)
> # {
> #     real  r;
> #     float f;
> #
> #     if (!s.length)
> #         goto Lerr;
> #
> #     r = toReal(s);
> #     f = cast(float)r;
> #
> #     if (feq(cast(real)f, r) != 1)
> #         if (toString(f) != toString(r))
> #             goto Loverflow;
> #
> #     return cast(float)r;
> #
> #     Loverflow:
> #         conv_overflow(s);
> #
> #     Lerr:
> #         conv_error(s);
> #         return 0f;
> # }
> #
> # unittest
> # {
> #     debug( conv ) writefln( "conv.toFloat.unittest" );
> #     float f;
> #
> #     f = toFloat( "123" );
> #     assert( f == 123f );
> #     f = toFloat( "+123" );
> #     assert( f == +123f );
> #     f = toFloat( "-123" );
> #     assert( f == -123f );
> #     f = toFloat( "123e+2" );
> #     assert( f == 123e+2f );
> #
> #     f = toFloat( "123e-2" );
> #     assert( f == 123e-2f );
> #     f = toFloat( "123." );
> #     assert( f == 123.f );
> #     f = toFloat( ".456" );
> #     assert( f == .456f );
> #
> #     //Min and Max values
> #     f = toFloat("1.17549e-38");
> #     assert(feq(cast(real)f, cast(real)1.17549e-38));
> #     assert(feq(cast(real)f, cast(real)float.min));
> #     f = toFloat("3.40282e+38");
> #     assert(toString(f) == toString(3.40282e+38));
> #
> #     //nan
> #     f = toFloat("nan");
> #     assert(toString(f) == toString(float.nan));
> # }
> #
> # /***************************************************************
> #  * Convert character string to double.
> #  * Grammar:
> #  * ['+'|'-'] digit {digit}
> #  */
> # double toDouble(in char[] s)
> # {
> #     real   r;
> #     double d;
> #
> #     if (!s.length)
> #         goto Lerr;
> #
> #     r = toReal(s);
> #     d = cast(double)r;
> #
> #     if (feq(r, cast(real)d) != 1)
> #         if (toString(d) != toString(r))
> #             goto Loverflow;
> #
> #     return cast(double)r;
> #
> #     Loverflow:
> #         conv_overflow(s);
> #
> #     Lerr:
> #         conv_error(s);
> #         return 0;
> # }
> #
> # unittest
> # {
> #     debug( conv ) writefln( "conv.toDouble.unittest" );
> #     double d;
> #
> #     d = toDouble( "123" );
> #     assert( d == 123 );
> #     d = toDouble( "+123" );
> #     assert( d == +123 );
> #     d = toDouble( "-123" );
> #     assert( d == -123 );
> #     d = toDouble( "123e2" );
> #     assert( d == 123e2);
> #     d = toDouble( "123e-2" );
> #     assert( d == 123e-2 );
> #     d = toDouble( "123." );
> #     assert( d == 123. );
> #     d = toDouble( ".456" );
> #     assert( d == .456 );
> #     d = toDouble( "1.23456E+2" );
> #     assert( d == 1.23456E+2 );
> #
> #     //Min and Max values
> #     d = toDouble("2.22507e-308");
> #     assert(feq(cast(real)d, cast(real)2.22507e-308));
> #     assert(feq(cast(real)d, cast(real)double.min));
> #     d = toDouble("1.79769e+308");
> #     assert(toString(d) == toString(1.79769e+308));
> #     assert(toString(d) == toString(double.max));
> #
> #     //nan
> #     d = toDouble("nan");
> #     assert(toString(d) == toString(double.nan));
> # }
> #
> # /***************************************************************
> #  * Convert character string to real.
> #  * Grammar:
> #  * ['+'|'-'] digit {digit}
> #  */
> # real toReal(in char[] s)
> # {
> #     char[] sx;
> #     bit    b;
> #
> #     if (!s.length)
> #         goto Lerr;
> #
> #     b = getFloatStrings(s, sx);
> #
> #     if (b == 0)
> #         goto Lerr;
> #
> #     return atof(sx);
> #
> #     Lerr:
> #         conv_error(s);
> #         return 0.0L;
> # }
> #
> # unittest
> # {
> #     debug(conv) writefln("conv.toReal.unittest");
> #     real r;
> #
> #     r = toReal("123");
> #     assert(r == 123L);
> #     r = toReal("+123");
> #     assert(r == 123L);
> #     r = toReal("-123");
> #     assert(r == -123L);
> #     r = toReal("123e2");
> #     assert(feq(r, 123e2L));
> #     r = toReal("123e-2");
> #     assert(feq(r, 1.23L));
> #     r = toReal("123.");
> #     assert(r == 123L);
> #     r = toReal(".456");
> #     assert(r == .456L);
> #
> #     r = toReal("1.23456e+2");
> #     assert(feq(r,  1.23456e+2L));
> #     r = toReal(toString(real.max / 2L));
> #     assert(toString(r) == toString(real.max / 2L));
> #
> #     //Min and Max values
> #     r = toReal(toString(real.min));
> #     assert(toString(r) == toString(real.min));
> #     r = toReal(toString(real.max));
> #     assert(toString(r) == toString(real.max));
> #
> #     //nan
> #     r = toReal("nan");
> #     assert(toString(r) == toString(real.nan));
> # }
> #
> # /***************************************************************
> #  * Convert character string to ifloat.
> #  * Grammar:
> #  * ['+'|'-'] digit {digit}
> #  */
> # ifloat toIfloat(in char[] s)
> # {
> #     real   r;
> #     ireal  ir;
> #     ifloat ift;
> #
> #     if (!s.length)
> #         goto Lerr;
> #
> #     r   = toReal(s);
> #     ir  = cast(ireal)(r * 1.0i);
> #     ift = cast(ifloat)(r * 1.0i);
> #
> #     if (feq(ir, cast(ireal)ift) != 1)
> #         goto Loverflow;
> #
> #     return ift;
> #
> #     Loverflow:
> #         conv_overflow(s);
> #
> #     Lerr:
> #         conv_error(s);
> #         return cast(ifloat)0.0i;
> # }
> #
> # unittest
> # {
> #     debug(conv) writefln("conv.toIfloat.unittest");
> #     ifloat ift;
> #
> #     ift = toIfloat(toString(ifloat.min));
> #
> #     assert(toString(ift) == toString(ifloat.min) );
> #     assert(feq(cast(ireal)ift, cast(ireal)ifloat.min));
> #
> #     ift = toIfloat(toString(ifloat.max));
> #     assert(toString(ift) == toString(ifloat.max));
> #     assert(feq(cast(ireal)ift, cast(ireal)ifloat.max));
> #
> #     ift = toIfloat(toString(123.45));
> #     assert(toString(ift) == toString(123.45i));
> #
> #     ift = toIfloat(toString(456.77i));
> #     assert(toString(ift) == toString(456.77i));
> #
> #     ift = toIfloat(toString(ifloat.nan));
> #     assert(toString(ift.nan) == toString(ifloat.nan));
> #     assert(feq(cast(ireal)ift, cast(ireal)ifloat.nan));
> # }
> #
> # /***************************************************************
> #  * Convert character string to idouble.
> #  * Grammar:
> #  * ['+'|'-'] digit {digit}
> #  */
> # idouble toIdouble(in char[] s)
> # {
> #     real    r;
> #     ireal   ir;
> #     idouble id;
> #
> #     if (!s.length)
> #         goto Lerr;
> #
> #     r  = toReal(s);
> #     ir = cast(ireal)(r * 1.0i);
> #     id = cast(idouble)(r * 1.0i);
> #
> #     if (feq(ir, cast(ireal)id) != 1)
> #         goto Loverflow;
> #
> #     return id;
> #
> #     Loverflow:
> #         conv_overflow(s);
> #
> #     Lerr:
> #         conv_error(s);
> #         return cast(idouble)0.0i;
> # }
> #
> # unittest
> # {
> #     debug(conv) writefln("conv.toIdouble.unittest");
> #     idouble id;
> #
> #     id = toIdouble(toString(idouble.min));
> #     assert(toString( id ) == toString(idouble.min));
> #     assert(feq(cast(ireal)id.re, cast(ireal)idouble.min.re));
> #     assert(feq(cast(ireal)id.im, cast(ireal)idouble.min.im));
> #
> #     id = toIdouble(toString(idouble.max));
> #     assert(toString(id) == toString(idouble.max));
> #     assert(feq(cast(ireal)id.re, cast(ireal)idouble.max.re));
> #     assert(feq(cast(ireal)id.im, cast(ireal)idouble.max.im));
> #
> #     id = toIdouble(toString("123.45"));
> #     assert(id == 123.45i);
> #
> #     id = toIdouble(toString(idouble.nan));
> #     assert(toString(id.nan) == toString(idouble.nan));
> # }
> #
> # /***************************************************************
> #  * Convert character string to ireal.
> #  * Grammar:
> #  * ['+'|'-'] digit {digit}
> #  */
> # ireal toIreal(in char[] s)
> # {
> #     real  r;
> #     ireal ir;
> #
> #     if (!s.length)
> #         goto Lerr;
> #
> #     r = toReal(s);
> #
> #     ir = cast(ireal)(r * 1.0i);
> #
> #     return ir;
> #
> #     Lerr:
> #         conv_error(s);
> #         return cast(ireal)0.0i;
> # }
> #
> # unittest
> # {
> #     debug(conv) writefln("conv.toIreal.unittest");
> #     ireal ir;
> #
> #     ir = toIreal(toString(ireal.min));
> #     assert(toString(ir) == toString(ireal.min));
> #     assert(feq(cast(real)ir.re, cast(real)ireal.min.re));
> #     assert(feq(cast(real)ir.im, cast(real)ireal.min.im));
> #
> #     ir = toIreal(toString(ireal.max));
> #     assert(toString(ir) == toString(ireal.max));
> #     assert(feq(cast(real)ir.re, cast(real)ireal.max.re));
> #
> #     ir = toIreal(toString("123.45"));
> #     assert(feq(cast(real)ir.re, cast(real)123.45i));
> #
> #     ir = toIreal(toString(ireal.nan));
> #     assert(toString(ir.nan) == toString(ireal.nan));
> # }
> #
> # /***************************************************************
> #  * Convert character string to cfloat.
> #  * Grammar:
> #  * ['+'|'-'] digit {digit}
> #  */
> # cfloat toCfloat(in char[] s)
> # {
> #     char[] s1;
> #     char[] s2;
> #     real   r1;
> #     real   r2;
> #     creal  cr;
> #     cfloat cf;
> #     bit    b = 0;
> #
> #     if (!s.length)
> #         goto Lerr;
> #
> #     b = getFloatStrings(s, s1, s2);
> #
> #     if (b == 0)
> #         goto Lerr;
> #
> #     r1 = atof(s1);
> #     r2 = atof(s2);
> #
> #     cr = cast(creal)cast(creal)r1 + cast(creal)(r2 * 1.0i);
> #     cf = cast(cfloat)r1 + cast(cfloat)(r2 * 1.0i);
> #
> #     if (feq(cr, cast(creal)cf) != 1)
> #         goto Loverflow;
> #
> #     return cf;
> #
> #     Loverflow:
> #         conv_overflow(s);
> #
> #     Lerr:
> #         conv_error(s);
> #         return cast(cfloat)0.0e-0+0i;
> # }
> #
> # unittest
> # {
> #     debug(conv) writefln("conv.toCfloat.unittest");
> #     cfloat cf;
> #
> #     cf = toCfloat(toString(cfloat.min));
> #     assert(toString(cf) == toString(cfloat.min));
> #
> #     cf = toCfloat(toString(cfloat.max));
> #     assert(toString(cf) == toString(cfloat.max));
> #
> #     cf = toCfloat(toString("1.2345e-5+0i"));
> #     assert(toString(cf) == toString(1.2345e-5+0i));
> #     assert(feq(cf, 1.2345e-5+0i));
> # }
> #
> # /***************************************************************
> #  * Convert character string to cdouble.
> #  * Grammar:
> #  * ['+'|'-'] digit {digit}
> #  */
> # cdouble toCdouble(in char[] s)
> # {
> #     char[]  s1;
> #     char[]  s2;
> #     real    r1;
> #     real    r2;
> #     creal   cr;
> #     cdouble cd;
> #     bit     b = 0;
> #
> #     if (!s.length)
> #         goto Lerr;
> #
> #     b = getFloatStrings(s, s1, s2);
> #
> #     if (b == 0)
> #         goto Lerr;
> #
> #     r1 = atof(s1);
> #     r2 = atof(s2);
> #
> #     cr = cast(creal)cast(creal)r1 + cast(creal)(r2 * 1.0i);
> #     cd = cast(cdouble)r1 + cast(cdouble)(r2 * 1.0i);
> #
> #     if (feq(cr, cast(creal)cd) != 1)
> #         goto Loverflow;
> #
> #     return cd;
> #
> #     Loverflow:
> #         conv_overflow(s);
> #
> #     Lerr:
> #         conv_error(s);
> #         return cast(cdouble)0.0e-0+0i;
> # }
> #
> # unittest
> # {
> #     debug(conv) writefln("conv.toCdouble.unittest");
> #     cdouble cd;
> #
> #     cd = toCdouble(toString(cdouble.min));
> #     assert(toString(cd) == toString(cdouble.min));
> #
> #     cd = toCdouble(toString(cdouble.max));
> #     assert(toString( cd ) == toString(cdouble.max));
> #
> #     cd = toCdouble(toString("1.2345e-5+0i"));
> #     assert(toString( cd ) == toString(1.2345e-5+0i));
> #     assert(feq(cd, 1.2345e-5+0i));
> # }
> #
> # /***************************************************************
> #  * Convert character string to creal.
> #  * Grammar:
> #  * ['+'|'-'] digit {digit}
> #  */
> # creal toCreal(in char[] s)
> # {
> #     char[] s1;
> #     char[] s2;
> #     real   r1;
> #     real   r2;
> #     creal  cr;
> #     bit    b = 0;
> #
> #     if (!s.length)
> #         goto Lerr;
> #
> #     b = getFloatStrings(s, s1, s2);
> #
> #     if (b == 0)
> #         goto Lerr;
> #
> #     r1 = atof(s1);
> #     r2 = atof(s2);
> #
> #     if (r2 != 0.0)
> #         cr = cast(creal)(r1 + (r2 * 1.0i));
> #     else
> #         cr = cast(creal)(r1 + cast(creal)0.0i);
> #
> #     return cr;
> #
> #     Lerr:
> #         conv_error(s);
> #         return cast(creal)0.0e-0+0i;
> # }
> #
> # unittest
> # {
> #     debug(conv) writefln("conv.toCreal.unittest");
> #     creal cr;
> #
> #     cr = toCreal(toString(creal.min));
> #     assert(toString(cr) == toString(creal.min));
> #     assert(feq(cr, creal.min));
> #
> #     cr = toCreal(toString(creal.max));
> #     assert(toString(cr) == toString(creal.max));
> #     assert(feq(cr, creal.max));
> #
> #     cr = toCreal(toString("1.2345e-5+0i"));
> #     assert(toString(cr) == toString(1.2345e-5+0i));
> #     assert(feq(cr, 1.2345e-5+0i));
> #
> #     cr = toCreal(toString("0.0e-0+0i"));
> #     assert(toString(cr) == toString(0.0e-0+0i));
> #     assert(cr == 0.0e-0+0i);
> #     assert(feq(cr, 0.0e-0+0i));
> #
> #     cr = toCreal("123");
> #     assert(cr == 123);
> #
> #     cr = toCreal("+5");
> #     assert(cr == 5);
> #
> #     cr = toCreal("-78");
> #     assert(cr == -78);
> # }
> #
> # /***************************************************************
> #  * Validates a character string for the following datatypes:
> #  * float, double, real, ifloat, idouble, and ireal
> #  * Grammar:
> #  * ['+'|'-'] string floating-point digit {digit}
> #  * also allows ".", "i", "f", "L", "e" within the string
> #  */
> # private bit getFloatStrings(in char[] s, out char[] s1)
> # {
> #      char[] s2 = "0";
> #
> #      return getFloatStrings(s, s1, s2);
> # }
> #
> # /***************************************************************
> #  * Validates and modified a character string for the following datatype:
> #  * cfloat, cdouble, and creal
> #  * Grammar:
> #  * ['+'|'-'] string floating-point digit {digit}
> #  * also allows ".", "i", "f", "L", "e" within the string
> #  *
> #  * s1 returns the first number from the string
> #  * s2 returns the second (or zeroed out) number from the string
> #  */
> # private bit getFloatStrings(in char[] s, out char[] s1, out char[] s2)
> # {
> #     char[][] a;
> #     char[]   w   = s.dup;
> #     int      len = w.length;
> #
> #     if (!len)
> #         goto Lerr;
> #
> #     // Returns: 0 = error, 1 = ok to use
> #     bit isFloatingValue(in char[] s)
> #     {
> #         char c;
> #         int  len = s.length;
> #         int  periods = 0;
> #
> #         for (int i = 0; i < len; i++)
> #         {
> #             c = s[i];
> #
> #             // Set the following characters to lowercase.
> #             if (c == 'E' || c == 'I' || c == 'F')
> #             {
> #                 s[i] = c + (cast(char)'a' - 'A');
> #                 c = s[i];
> #             }
> #
> #             if (c >= '0' && c <= '9')
> #                 continue;
> #             else if (((c == '-') && (i != len - 1)) && len != 1)
> #                 continue;
> #             else if (((c == '+') && (i != len - 1)) && len != 1)
> #                 continue;
> #             else if (((c == 'e') && (i != len - 1)) && len != 1)
> #                 continue;
> #             else if (c == '.' && periods <= 2 && len != 1)
> #             {
> #                 periods++;
> #                 continue;
> #             }
> #             else if (((c == 'i') && (i == len - 1)) && len != 1)
> #                 continue;
> #             else if (((c == 'f') && (i == len - 1)) && len != 1 )
> #                 continue;
> #             else if (((c == 'L') && (i == len - 1)) && len != 1)
> #                 continue;
> #             else
> #                 return 0;
> #         }
> #
> #         return 1;
> #     }
> #
> #     // When "nan" or "nani" just return them.
> #     if (w == "nan" || w == "nani")
> #     {
> #         s1 = w;
> #         s2 = "0e+0";
> #         return 1;
> #     }
> #
> #     // Split the original string out into two strings.
> #     for (int i = 1; i < len; i++)
> #         if ((w[i - 1] != 'e' && w[i - 1] != 'E') && w[i] == '+')
> #         {
> #             w[i] = '^';
> #             a = split(w, "^");
> #             break;
> #         }
> #
> #     // Handle the case when there's only a single value
> #     //  to work with, and set the other string to zero.
> #     if (a.length == 0)
> #         a = split(w ~ "^0e+0", "^");
> #
> #     // Check the first string.
> #     if (isFloatingValue(a[0]))
> #         s1 = a[0].dup;
> #     else
> #         goto Lerr;
> #
> #     // Check the second string.
> #     if (isFloatingValue(a[1]))
> #         s2 = a[1].dup;
> #     else
> #         goto Lerr;
> #
> #     // String is good enough to pass
> #     // into the atof() function. :)
> #     return 1;
> #
> #     Lerr:
> #         // Display the original string in the error message.
> #         conv_error("\"" ~ s ~ "\"");
> #         return 0;
> # }
> #
> # unittest
> # {
> #     debug(conv) writefln("conv.getFloatStrings.unittest");
> #     char[] s1;
> #     char[] s2;
> #     bit    b = 0;
> #
> #     static char[][] errors =
> #     [
> #         "",
> #         "-",
> #         "+",
> #         "-+",
> #         " ",
> #         " 0",
> #         "0 ",
> #         "- 0",
> #         "1-",
> #         "xx",
> #         "123h",
> #     ];
> #
> #     for (int j = 0; j < errors.length; j++)
> #     {
> #         b = 1;
> #         try
> #         {
> #             b = getFloatStrings(errors[j], s1, s2);
> #         }
> #         catch (Error e)
> #         {
> #             debug(conv) e.print();
> #             b = 0;
> #         }
> #         assert(b == 0);
> #     }
> # }
> #
> # /****************************************
> #  * Main function tp compare reals with given precision
> #  */
> # private bit feq(in real rx, in real ry, in real precision)
> # {
> #     if (rx == ry)
> #         return 1;
> #
> #     if (isnan(rx))
> #         return cast(bit)isnan(ry);
> #
> #     if (isnan(ry))
> #         return 0;
> #
> #     return cast(bit)(fabs(rx - ry) <= precision);
> # }
> #
> # /****************************************
> #  * (Note: Copied here from std.math's mfeq() function for unittesting)
> #  * Simple function to compare two floating point values
> #  * to a specified precision.
> #  * Returns:
> #  *  1   match
> #  *  0   nomatch
> #  */
> #  private bit feq(in real r1, in real r2)
> # {
> #     if (r1 == r2)
> #         return 1;
> #
> #     if (isnan(r1))
> #         return cast(bit)isnan(r2);
> #
> #     if (isnan(r2))
> #         return 0;
> #
> #     return cast(bit)(feq(r1, r2, 0.000001L));
> # }
> #
> # /****************************************
> #  * compare ireals with given precision
> #  */
> # private bit feq(in ireal r1, in ireal r2)
> # {
> #     real rx = cast(real)r1;
> #     real ry = cast(real)r2;
> #
> #     if (rx == ry)
> #         return 1;
> #
> #     if (isnan(rx))
> #         return cast(bit)isnan(ry);
> #
> #     if (isnan(ry))
> #         return 0;
> #
> #     return feq(rx, ry, 0.000001L);
> # }
> #
> # /****************************************
> #  * compare creals with given precision
> #  */
> # private bit feq(in creal r1, in creal r2)
> # {
> #     real r1a = fabs(cast(real)r1.re - cast(real)r2.re);
> #     real r2b = fabs(cast(real)r1.im - cast(real)r2.im);
> #
> #     if ((cast(real)r1.re == cast(real)r2.re) &&
> #         (cast(real)r1.im == cast(real)r2.im))
> #         return 1;
> #
> #     if (isnan(r1a))
> #         return cast(bit)isnan(r2b);
> #
> #     if (isnan(r2b))
> #         return 0;
> #
> #     return feq(r1a, r2b, 0.000001L);
> # }
> # //*** End of insert ***
>
>
>
> -------------------------------------------------------------------
> "Dare to reach for the Stars...Dare to Dream, Build, and Achieve!"
> -------------------------------------------------------------------
>
> MKoD: http://spottedtiger.tripod.com/D_Language/D_Main_XP.html


April 22, 2005
Some comments about getFloatStrings. I also looked at the definition of atof in std.string. It calls strtold and throws away the end ptr. You might want to directly call strtold and use the end ptr instead of calling atof. Or, since atof calls toStringz, you might want to manage that better, too, since toStringz can (and probably will) dup strings.

> # /***************************************************************
> #  * Validates and modified a character string for the following datatype:
> #  * cfloat, cdouble, and creal
> #  * Grammar:
> #  * ['+'|'-'] string floating-point digit {digit}
> #  * also allows ".", "i", "f", "L", "e" within the string

Why look for f and L?

> #  *
> #  * s1 returns the first number from the string
> #  * s2 returns the second (or zeroed out) number from the string
> #  */
> # private bit getFloatStrings(in char[] s, out char[] s1, out char[] s2)
> # {
> #     char[][] a;
> #     char[]   w   = s.dup;
> #     int      len = w.length;
> #
> #     if (!len)
> #         goto Lerr;
> #
> #     // Returns: 0 = error, 1 = ok to use
> #     bit isFloatingValue(in char[] s)
> #     {
> #         char c;
> #         int  len = s.length;
> #         int  periods = 0;
> #
> #         for (int i = 0; i < len; i++)
> #         {
> #             c = s[i];
> #
> #             // Set the following characters to lowercase.
> #             if (c == 'E' || c == 'I' || c == 'F')
> #             {
> #                 s[i] = c + (cast(char)'a' - 'A');
> #                 c = s[i];
> #             }

Why change to lower case? If atof needs lower case then I'd say only accept lower case strings.

> #
> #             if (c >= '0' && c <= '9')
> #                 continue;
> #             else if (((c == '-') && (i != len - 1)) && len != 1)
> #                 continue;
> #             else if (((c == '+') && (i != len - 1)) && len != 1)
> #                 continue;
> #             else if (((c == 'e') && (i != len - 1)) && len != 1)
> #                 continue;
> #             else if (c == '.' && periods <= 2 && len != 1)
> #             {
> #                 periods++;
> #                 continue;
> #             }
> #             else if (((c == 'i') && (i == len - 1)) && len != 1)
> #                 continue;
> #             else if (((c == 'f') && (i == len - 1)) && len != 1 )
> #                 continue;
> #             else if (((c == 'L') && (i == len - 1)) && len != 1)
> #                 continue;
> #             else
> #                 return 0;
> #         }
> #
> #         return 1;
> #     }
> #
> #     // When "nan" or "nani" just return them.
> #     if (w == "nan" || w == "nani")
> #     {
> #         s1 = w;
> #         s2 = "0e+0";
> #         return 1;
> #     }
> #
> #     // Split the original string out into two strings.
> #     for (int i = 1; i < len; i++)
> #         if ((w[i - 1] != 'e' && w[i - 1] != 'E') && w[i] == '+')
> #         {
> #             w[i] = '^';
> #             a = split(w, "^");
> #             break;
> #         }
> #
> #     // Handle the case when there's only a single value
> #     //  to work with, and set the other string to zero.
> #     if (a.length == 0)
> #         a = split(w ~ "^0e+0", "^");

Why use split here? Don't you know exactly where split will actually split?

> #
> #     // Check the first string.
> #     if (isFloatingValue(a[0]))
> #         s1 = a[0].dup;
> #     else
> #         goto Lerr;
> #
> #     // Check the second string.
> #     if (isFloatingValue(a[1]))
> #         s2 = a[1].dup;
> #     else
> #         goto Lerr;
> #
> #     // String is good enough to pass
> #     // into the atof() function. :)
> #     return 1;
> #
> #     Lerr:
> #         // Display the original string in the error message.
> #         conv_error("\"" ~ s ~ "\"");
> #         return 0;
> # }


April 23, 2005
In article <d4b13j$2iaj$1@digitaldaemon.com>, Ben Hinkle says...
>
>Some comments about getFloatStrings. I also looked at the definition of atof in std.string. It calls strtold and throws away the end ptr. You might want to directly call strtold and use the end ptr instead of calling atof. Or, since atof calls toStringz, you might want to manage that better, too, since toStringz can (and probably will) dup strings.
>

Ben many thanks for all your advise! I've made the changes in your suggestions, and have hopefully answered all your questions in my newest post for a final review.

Post can be found here: http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/22358

I hope you'll look over the newest version, and make a few comments.

Thanks again for you help,
David L.

-------------------------------------------------------------------
"Dare to reach for the Stars...Dare to Dream, Build, and Achieve!"
-------------------------------------------------------------------

MKoD: http://spottedtiger.tripod.com/D_Language/D_Main_XP.html