David L. Davis
Posted in reply to Walter
| In article <d2cb5d$2757$1@digitaldaemon.com>, Walter says...
>
> ...
>
>I suggest emailing me the changes and posting them to the newsgroup. The former means I won't miss them in the flood of messages here, and the latter means that others can use them immediately and/or comment on them. Many proposed additions I have no idea whether they are widely useful enough to be in Phobos or not; posting them in the n.g. will help with that. I don't want to fill Phobos up with functions of marginal utility, it needs to be widely useful, core building blocks. Some help making that determination would be much appreciated.
>
> ...
>
Ok, here's the code that I sent to Walter that I thought would be very useful to all, which I thought would complete std.conv to handle all the numerical data types. Please, feel free to improve, and / or give comments.
The original message, "Extending std.conv with floating-point wrapper functions" posted 09.Nov.04 can be found here: (http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/12382)
Also I've eMailed this code below to Walter on 03.Mar.05 for extending std.conv for floating-point conversions.
The main point being: that since there are toString() functions in std.string to change floating points into char[]s, why couldn't I find any functions to change them back to floating point? Therefore, it seemed a bit odd to me why std.conv was so incomplete...since it did only whole number conversions; so I decided to write some D code (that's below) to solve that issue.
---------------------------------
This is same code that I eMailed to Walter for inclusion into std.conv.
# /+
# ' Module : convext.d - "char[] to floating-point number"
# ' : wrapper functions.
# ' Version : v0.1 beta WIP
# ' :
# ' Author(s) : David L. 'SpottedTiger' Davis for the wrapper
# ' : functions / unittests, Pavel "EvilOne" Minayev for
# ' : writing the std.math2 code that does most of the work,
# ' : and to Walter Bright for the great D compiler, as well
# ' : as the D's Phobos runtime library filled with very useful
# ' : modules and functions...of which the std.math2 module
# ' : is a part of.
# ' :
# ' Created Date : 07.Nov.04 Complied and Tested with dmd v0.105
# ' Modified Date : 09.Nov.04 Added unitconvext code, recompiled
# ' : and tested with dmd v0.106.
# ' : 20.Jan.05 Recompiled and tested with dmd v0.111.
# ' :
# ' Requirements : std.string for the ifind() and find() functions, and
# ' : std.math2 for both the atof() and feq() functions.
# ' :
# ' Licence : DigitalMars (waiting for this to be included into
# ' : std.conv.d, at which time this code will be pulled
# ' : totally from this site.)
# ' -------------------------------------------------------------------------
# ' Note: 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 complie for a unittest:
# ' C:\dmd>bin\dmd convext.d -debug=convext -unittest
# '
# ' To compile a D program that use convext.d:
# ' C:\dmd>bin\dmd MySource.d convext.d
# '
# ' Public functions:
# ' ------------------------------
# ' 01) bit toBit( in char )
# ' 02) bit toBit( in char[] )
# ' 03) float toFloat( in char[] )
# ' 04) double toDouble( in char[] )
# ' 05) real toReal( in char[] )
# ' 06) ifloat toIfloat( in char[] )
# ' 07) idouble toIdouble( in char[] )
# ' 08) ireal toIreal( in char[] )
# ' 09) cfloat toCfloat( in char[] )
# ' 10) cdouble toCdouble( in char[] )
# ' 11) creal toCreal( in char[] )
# '
# ' Private functions:
# ' ------------------------------
# ' 01) void getComplexStrings( in char[], out char[], out char[] )
# '
# +/
# module convext;
#
# private import std.math2;
# private import std.string;
#
# debug( convext ) 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
# {
# debug( convext ) 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
# {
# debug( convext ) 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
# {
# debug( convext ) 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
# {
# debug( convext ) 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
# {
# debug( convext ) 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
# {
# debug( convext ) 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
# {
# debug( convext ) 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
# {
# debug( convext ) 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
# {
# debug( convext ) 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
# {
# debug( convext ) 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
# {
# debug( convext ) 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( convext )
# {
# int main()
# {
# writefln( "convext.unittests done!" );
# return 0;
#
# } // end int main()
# }
David L.
-------------------------------------------------------------------
"Dare to reach for the Stars...Dare to Dream, Build, and Achieve!"
|