www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Requesting a 2nd review: on the floating-point funcs for conv.d

reply David L. Davis <SpottedTiger yahoo.com> writes:
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
Apr 16 2005
next sibling parent reply "TechnoZeus" <TechnoZeus PeoplePC.com> writes:
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

Apr 21 2005
parent reply pragma <pragma_member pathlink.com> writes:
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
Apr 21 2005
parent "TechnoZeus" <TechnoZeus PeoplePC.com> writes:
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

Apr 21 2005
prev sibling next sibling parent "Ben Hinkle" <ben.hinkle gmail.com> writes:
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 

Apr 22 2005
prev sibling parent reply "Ben Hinkle" <bhinkle mathworks.com> writes:
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;
 # }

Apr 22 2005
parent David L. Davis <SpottedTiger yahoo.com> writes:
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: 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
Apr 23 2005