November 09, 2004
I was looking into the std.conv module the other evening, and I had thought it had conversion functions for all of the D numerical types, but sadly I discovered that it only did the whole-number types. So the next evening I looked around and found std.string.atof() that does only float and double, and std.math2's "real atof( in char[] )" function, which does a pretty good job with float, double, and real right out of the box. With a bit of playing around with std.math2 yet the next evening I managed to make some useful wrapper functions that worked well with D's remaining floating-point types: ifloat, idouble, ireal, cfloat, cdouble, and creal.

I really think it would be great if Walter would add these functions, or functions like these to the std.conv before D v1.0. It would make std.conv more complete, and on top of that, it would save a person's time looking all around for functions to convert number-types that were converted with std.string.toString() functions back to their original D's numerical value(s).

Anyways here's the code, hopefully someone will find it useful... also I'll add this code to my web-site in a day or two for downloading.

# /+
#  ' The main purpose of this code is to extend std.conv, with some
#  ' useful "char[] to floating-point number" wrapper functions...
#  ' which mainly uses the "real std.math2.atof( in char[] )" function
#  ' for all the conversions.
#  '
#  ' To compile for a unittest:
#  ' C:\dmd>bin\dmd convext.d -debug=test -unittest
#  +/
# module convext;
#
# private import std.math2;
# private import std.string;
# private import std.stdio;
#
# bit toBit( in char c )
# {
#     if ( c == 't' || c == 'T' || c == '1' ||
#          c == 'Y' || c == 'y' )
#         c = '1';
#
#     return ( c == '1' ? true : false );
# }
#
# unittest
# {
#     writefln( "convext.toBit( in char ).unittest" );
#     bit b;
#
#     b = toBit( 'T' );
#     assert( b == true );
#     b = toBit( 'f' );
#     assert( b == false );
#     b = toBit( 'x' );
#     assert( b == false );
#     b = toBit( 'n' );
#     assert( b == false );
# }
#
# bit toBit( in char[] s )
# {
#     char[] s1 = std.string.toupper( s );
#
#     if ( s1 == "TRUE" || s1 == "T" || s1 == "1" ||
#          s1 == "Y" || s1 == "YES" || s1 == "ON" )
#         s1 = "1";
#
#     return ( s1 == "1" ? true : false );
# }
#
# unittest
# {
#     writefln( "convext.toBit( in char[] ).unittest" );
#     bit b;
#
#     b = toBit( "True" );
#     assert( b == true );
#     b = toBit( "Xta" );
#     assert( b == false );
#     b = toBit( "" );
#     assert( b == false );
#     b = toBit( "yeS" );
#     assert( b == true );
# }
#
# float toFloat( in char[] s )
# {
#     return cast(float)std.math2.atof( s );
# }
#
# unittest
# {
#     writefln( "convext.toFloat( in char[] ).unittest" );
#     float f;
#
#     f = toFloat( "123" );
#     assert( std.math2.feq( f, 123 ) );
#     f = toFloat( "+123" );
#     assert( std.math2.feq( f, 123 ) );
#     f = toFloat( "-123" );
#     assert( std.math2.feq( f, -123 ) );
#     f = toFloat( "123e2" );
#     assert( std.math2.feq( f, 12300 ) );
#
#     f = toFloat( "123e-2" );
#     assert( std.math2.feq( f, 1.23 ) );
#     f = toFloat( "123." );
#     assert( std.math2.feq( f, 123 ) );
#     f = toFloat( ".456" );
#     assert( std.math2.feq( f, .456 ) );
#     f = toFloat( "1.23456E+2" );
#     //from real to float 123.456 became 123.456001
#     assert( std.math2.feq( f, 123.456, 0.0001 ) );
# }
#
# double toDouble( in char[] s )
# {
#     return cast(double)std.math2.atof( s );
# }
#
# unittest
# {
#     writefln( "convext.toDouble( in char[] ).unittest" );
#     double d;
#
#     d = toDouble( "123" );
#     assert( std.math2.feq( d, 123 ) );
#     d = toDouble( "+123" );
#     assert( std.math2.feq( d, 123 ) );
#     d = toDouble( "-123" );
#     assert( std.math2.feq( d, -123 ) );
#     d = toDouble( "123e2" );
#     assert( std.math2.feq( d, 12300 ) );
#
#     d = toDouble( "123e-2" );
#     assert( std.math2.feq( d, 1.23 ) );
#     d = toDouble( "123." );
#     assert( std.math2.feq( d, 123 ) );
#     d = toDouble( ".456" );
#     assert( std.math2.feq( d, .456 ) );
#     d = toDouble( "1.23456E+2" );
#     assert( std.math2.feq( d, 123.456 ) );
# }
#
# real toReal( in char[] s )
# {
#     return std.math2.atof( s );
# }
#
# unittest
# {
#     writefln( "convext.toReal( in char[] ).unittest" );
#     real r;
#
#     r = toReal( "123" );
#     assert( std.math2.feq( r, 123 ) );
#     r = toReal( "+123" );
#     assert( std.math2.feq( r, 123 ) );
#     r = toReal( "-123" );
#     assert( std.math2.feq( r, -123 ) );
#     r = toReal( "123e2" );
#     assert( std.math2.feq( r, 12300 ) );
#
#     r = toReal( "123e-2" );
#     assert( std.math2.feq( r, 1.23 ) );
#     r = toReal( "123." );
#     assert( std.math2.feq( r, 123 ) );
#     r = toReal( ".456" );
#     assert( std.math2.feq( r, .456 ) );
#     r = toReal( "1.23456E+2" );
#     assert( std.math2.feq( r, 123.456 ) );
#     r = toReal( std.string.toString( real.max / 2 ) );
#     assert( std.string.toString( r ) == std.string.toString( real.max / 2 ) );
#     r = toReal( std.string.toString( real.max ) );
#     assert( std.string.toString( r ) == std.string.toString( real.max ) );
# }
#
# ifloat toIfloat( in char[] s )
# {
#     return std.math2.atof( s[ 0 .. s.length - 1 ] ) * 1.0i;
# }
#
# unittest
# {
#     writefln( "convext.toIfloat( in char[] ).unittest" );
#     ifloat ift;
#
#     ift = toIfloat( std.string.toString( ifloat.min ) );
#     assert( std.string.toString( ift ) == std.string.toString( ifloat.min ) );
#
#     ift = toIfloat( std.string.toString( ifloat.max ) );
#     assert( std.string.toString( ift ) == std.string.toString( ifloat.max ) );
#
#     ift = toIfloat( std.string.toString( "123.45" ) );
#     assert( std.math2.feq( ift, 123.45i ) );
# }
#
# idouble toIdouble( in char[] s )
# {
#     return std.math2.atof( s[ 0 .. s.length - 1 ] ) * 1.0i;
# }
#
# unittest
# {
#     writefln( "convext.toIdouble( in char[] ).unittest" );
#     idouble id;
#
#     id = toIdouble( std.string.toString( idouble.min ) );
#     assert( std.string.toString( id ) == std.string.toString( idouble.min ) );
#
#     id = toIdouble( std.string.toString( idouble.max ) );
#     assert( std.string.toString( id ) == std.string.toString( idouble.max ) );
#
#     id = toIdouble( std.string.toString( "123.45" ) );
#     assert( std.math2.feq( id, 123.45i ) );
# }
#
# ireal toIreal( in char[] s )
# {
#     return std.math2.atof( s[ 0 .. s.length - 1 ] ) * 1.0i;
# }
#
# unittest
# {
#     writefln( "convext.toIreal( in char[] ).unittest" );
#     ireal ir;
#
#     ir = toIreal( std.string.toString( ireal.min ) );
#     assert( std.string.toString( ir ) == std.string.toString( ireal.min ) );
#
#     ir = toIreal( std.string.toString( ireal.max ) );
#     assert( std.string.toString( ir ) == std.string.toString( ireal.max ) );
#
#     ir = toIreal( std.string.toString( "123.45" ) );
#     assert( std.math2.feq( ir, 123.45i ) );
# }
#
# cfloat toCfloat( in char[] s )
# {
#     char[] s1;
#     char[] s2;
#
#     getComplexStrings( s, s1, s2 );
#
#     return cast(cfloat)std.math2.atof( s1 ) + cast(cfloat)std.math2.atof( s2 )
* 1.0i;
# }
#
# unittest
# {
#     writefln( "convext.toCfloat( in char[] ).unittest" );
#     cfloat cf;
#
#     cf = toCfloat( std.string.toString( cfloat.min ) );
#     assert( std.string.toString( cf ) == std.string.toString( cfloat.min ) );
#
#     cf = toCfloat( std.string.toString( cfloat.max ) );
#     assert( std.string.toString( cf ) == std.string.toString( cfloat.max ) );
#
#     cf = toCfloat( std.string.toString( "1.2345e-5+0i" ) );
#     assert( std.math2.feq( cf, 1.2345e-5+0i ) );
# }
#
# cdouble toCdouble( in char[] s )
# {
#     char[] s1;
#     char[] s2;
#
#     getComplexStrings( s, s1, s2 );
#
#     return cast(cdouble)std.math2.atof( s1 ) + cast(cdouble)std.math2.atof( s2
) * 1.0i;
# }
#
# unittest
# {
#     writefln( "convext.toCdouble( in char[] ).unittest" );
#     cdouble cd;
#
#     cd = toCdouble( std.string.toString( cdouble.min ) );
#     assert( std.string.toString( cd ) == std.string.toString( cdouble.min ) );
#
#     cd = toCdouble( std.string.toString( cdouble.max ) );
#     assert( std.string.toString( cd ) == std.string.toString( cdouble.max ) );
#
#     cd = toCdouble( std.string.toString( "1.2345e-5+0i" ) );
#     assert( std.math2.feq( cd, 1.2345e-5+0i ) );
# }
#
# creal toCreal( in char[] s )
# {
#     char[] s1;
#     char[] s2;
#
#     getComplexStrings( s, s1, s2 );
#
#     return cast(creal)std.math2.atof( s1 ) + cast(creal)std.math2.atof( s2 ) *
1.0i;
# }
#
# unittest
# {
#     writefln( "convext.toCreal( in char[] ).unittest" );
#     creal cr;
#
#     cr = toCreal( std.string.toString( creal.min ) );
#     assert( std.string.toString( cr ) == std.string.toString( creal.min ) );
#
#     cr = toCreal( std.string.toString( creal.max ) );
#     assert( std.string.toString( cr ) == std.string.toString( creal.max ) );
#
#     cr = toCreal( std.string.toString( "1.2345e-5+0i" ) );
#     assert( std.math2.feq( cr, 1.2345e-5+0i ) );
#
#     cr = toCreal( std.string.toString( "0.0e-0+0i" ) );
#     assert( std.math2.feq( cr, 0.0e-0+0i ) );
# }
#
# private void getComplexStrings( in char[] s, out char[] s1, out char[] s2 )
# {
#     int iPos1 = 0;
#     int iPos2 = 0;
#
#     s1 = s.dup;
#     s2 = "";
#
#     iPos1 = ifind( s1, "e+" );
#     if ( iPos1 != -1 )
#         iPos2 = find( s1[ iPos1 + 3 .. s1.length ], "+" );
#
#     if ( iPos1 == -1 )
#     {
#         iPos1 = ifind( s1, "e-" );
#         if ( iPos1 != -1 )
#             iPos2 = find( s1[ iPos1 + 3 .. s1.length ], "+" );
#     }
#
#     if ( iPos1 == -1 )
#         s1 = "0e+0";
#
#     if ( iPos2 != -1 )
#     {
#         iPos2 += iPos1;
#         s2 = s1[ iPos2 + 4 .. s1.length - 1 ].dup;
#         s1 = s1[ 0 .. iPos2 + 3 ];
#     }
#
#     //writefln( "getComplexStrings().s1=%s, s2=%s, iPos1=%d, iPos2=%d", s1,
s2, iPos1, iPos2 );
#
#     if ( iPos2 == -1 )
#     {
#         s1 = s1[ 0 .. s1.length - 1 ];
#         s2 = "0";
#     }
#
# } // end void getComplexStrings( in char[], out char[], out char[] )
#
# debug( test )
# {
# int main()
# {
#     writefln( "unittests done!" );
#     return 0;
#
# } // end int main()
# }

David L.

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