www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Extending std.conv with floating-point wrapper functions

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!"
Nov 08 2004