www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.announce - isNumeric.d - I'd like to contribute to Digital Mars D

reply David L. Davis <SpottedTiger yahoo.com> writes:
I'd like to share what I've written which may help others in their own D code,
and wish to contribute this code to Digital Mars D if Walter will accept it. I'm
not sure exactly which module this code would best fit in if it's accepted,
whether that would be in the std.string, std.math, or maybe in some a new
std.misc module.

But anyway, I found that I needed a isNumeric() function for my variant
(user-defined) datatype project, and already know I'll find it very useful in
checking for numeric strings. After creating this code, I decided to scan the
web for code others might have written for a isNumeric() function and to see if
I might have missed anything important in my own function. But, to my surprise I
found that most of them did something that was more of a isDigits() function
than a isNumeric() function...which I thought was pretty darn odd. Well, I hope
someone will find this code a tat-bit useful...enjoy! :)

# /+
#  ' Source        : isNumeric.d
#  ' Version       : v0.3
#  ' Author        : David L. 'SpottedTiger' Davis
#  ' Date Created  : 31.May.05 Compiled and Tested with dmd v0.125
#  ' Date Modified : 01.Jun.05 Modified the function to handle the
#  '               :           imaginary and complex float-point 
#  '               :           datatypes.
#  '               :
#  ' Licence       : Public Domain / Contributed to Digital Mars
#  ' --------------------------------------------------------------
#  ' To Complie : C:\dmd>dmd mycode.d isnumeric.d
#  ' To Unittest: C:\dmd>dmd isnumeric.d -debug=isnumeric -unittest
#  +/
# module isnumeric;
# 
# private import std.stdio;  // for writefln();
# private import std.string; // for tolower()
# private import std.stdarg; // for argument gathering
# private import std.utf;    // for toUTF8()
# 
# /+
#  ' final bool isNumeric(in char[], in bool = false)
#  ' ---------------------------------------------------------------
#  ' [in] char[] s can be formatted in the following ways:
#  '
#  ' Integer Whole Number:
#  ' (for byte, ubyte, short, ushort, int, uint, long, and ulong)
#  ' ['+'|'-']digit(s)[U|L|UL]
#  '
#  ' examples: 123, 123UL, 123L, +123U, -123L
#  '
#  ' Floating-Point Number:
#  ' (for float, double, real, ifloat, idouble, and ireal)
#  ' ['+'|'-']digit(s)[.][digit(s)][[e-|e+]digit(s)][i|f|L|Li|fi]]
#  '      or [nan|nani|inf|-inf]
#  '
#  ' examples: +123., -123.01, 123.3e-10f, 123.3e-10fi, 123.3e-10L
#  ' 
#  ' (for cfloat, cdouble, and creal)
#  ' ['+'|'-']digit(s)[.][digit(s)][[e-|e+]digit(s)][+]
#  '         [digit(s)[.][digit(s)][[e-|e+]digit(s)][i|f|L|Li|fi]]
#  '      or [nan|nani|nan+nani|inf|-inf]
#  '
#  ' examples: nan, -123e-1+456.9e-10Li, +123e+10+456i, 123+456
#  '
#  ' [in] bool bAllowSep 
#  ' False by default, but when set to true it will accept the 
#  ' separator characters "," and "_" within the string, but these  
#  ' characters should be stripped from the string before using any 
#  ' of the conversion functions like toInt(), toFloat(), and etc 
#  ' else an error will occur.
#  '
#  ' Also please note, that no spaces are allowed within the string  
#  ' anywhere whether it's a leading, trailing, or embedded space(s), 
#  ' thus they too must be stripped from the string before using this
#  ' function, or any of the conversion functions.
#  +/
# final bool isNumeric(in char[] s, in bool bAllowSep = false)
# {
#     int    iLen = s.length;
#     bool   bDecimalPoint = false;
#     bool   bExponent = false;
#     bool   bComplex = false;
#     char[] sx = std.string.tolower(s); 
#     int    j  = 0;
#     char   c;
# 
#     //writefln("isNumeric(char[], bool = false) called!");
#     // Empty string, return false
#     if (iLen == 0)
#         return false;
#     
#     // Check for NaN (Not a Number)
#     if (sx == "nan" || sx == "nani" || sx == "nan+nani")
#         return true;
#         
#     // Check for Infinity
#     if (sx == "inf" || sx == "-inf")
#         return true;
#      
#     // A sign is allowed only in the 1st character   
#     if (sx[0] == '-' || sx[0] == '+')
#         j++;
#             
#     for (int i = j; i < iLen; i++)
#     {
#         c = sx[i];
#     
#         // Digits are good, continue checking 
#         // with the next character... ;)
#         if (c >= '0' && c <= '9') 
#             continue;
# 
#         // Check for the complex type, and if found 
#         // reset the flags for checking the 2nd number.  
#         else if (c == '+')
#             if (i > 0) 
#             {
#                 bDecimalPoint = false;
#                 bExponent = false;
#                 bComplex = true;
#                 continue;
#             }
#             else
#                 return false;
#                 
#         // Allow only one exponent per number   
#         else if (c == 'e')  
#         {
#             // A 2nd exponent found, return not a number
#             if (bExponent)
#                 return false;
#                 
#             if (i + 1 < iLen)
#             {
#                 // Look forward for the sign, and if 
#                 // missing then this is not a number.
#                 if (sx[i + 1] != '-' && sx[i + 1] != '+')
#                     return false;
#                 else
#                 {
#                     bExponent = true;
#                     i++;    
#                 }    
#             }        
#             else
#                 // Ending in "E", return not a number
#                 return false;        
#         }  
#         // Allow only one decimal point per number to be used
#         else if (c == '.' )
#         {
#             // A 2nd decimal point found, return not a number
#             if (bDecimalPoint)
#                 return false;
#             
#             bDecimalPoint = true;
#             continue;
#         }   
#         // Check for ending literal characters: "f,u,l,i,ul,fi,li",
#         // and wheater they're being used with the correct datatype.
#         else if (i == iLen - 2)
#         {
#             // Integer Whole Number
#             if (sx[i..iLen] == "ul" && 
#                (!bDecimalPoint && !bExponent && !bComplex))
#                 return true;
#             // Floating-Point Number
#             else if ((sx[i..iLen] == "fi" || sx[i..iLen] == "li") &&
#                      (bDecimalPoint || bExponent || bComplex))
#                 return true;
#             else if (sx[i..iLen] == "ul" && 
#                     (bDecimalPoint || bExponent || bComplex))
#                 return false;    
#             // Could be a Integer or a Float, thus
#             // all these suffixes are valid for both  
#             else if (sx[i..iLen] == "ul" || 
#                      sx[i..iLen] == "fi" || 
#                      sx[i..iLen] == "li")
#                 return true;
#             else    
#                 return false;
#         }
#         else if (i == iLen - 1)
#         {
#             // Integer Whole Number
#             if ((c == 'u' || c == 'l') && 
#                 (!bDecimalPoint && !bExponent && !bComplex))
#                 return true;
#             // Check to see if the last character in the string 
#             // is the required 'i' character
#             else if (bComplex)
#                 if (c == 'i')
#                     return true;
#                 else 
#                     return false;        
#             // Floating-Point Number
#             else if ((c == 'l' || c == 'f' || c == 'i') &&
#                      (bDecimalPoint || bExponent))
#                 return true;
#             // Could be a Integer or a Float, thus  
#             // all these suffixes are valid for both 
#             else if (c == 'l' || c == 'f' || c == 'i')
#                 return true;
#             else
#                 return false;
#         }
#         else
#             // Check if separators are allow  
#             // to be in the numeric string
#             if (bAllowSep == true && (c == '_' || c == ','))
#                 continue;
#             else    
#                 return false;       
#     }     
#     
#     return true;
# }
# 
# // Allow any object as a parameter
# bool isNumeric(...)
# {
#     return isNumeric(_arguments, _argptr);
# }
# 
# // Check only the first parameter, all others will be ignored. 
# bool isNumeric(TypeInfo[] _arguments, va_list _argptr)
# {
#     char[]  s  = "";
#     wchar[] ws = "";
#     dchar[] ds = "";
# 
#     //writefln("isNumeric(...) called!");
#     if (_arguments.length == 0)
#         return false;
# 
#     if (_arguments[0] == typeid(char[]))
#         return isNumeric(va_arg!(char[])(_argptr));
#     else if (_arguments[0] == typeid(wchar[]))
#         return isNumeric(std.utf.toUTF8(va_arg!(wchar[])(_argptr)));
#     else if (_arguments[0] == typeid(dchar[]))
#         return isNumeric(std.utf.toUTF8(va_arg!(dchar[])(_argptr)));
#     else if (_arguments[0] == typeid(real))
#         return true;
#     else if (_arguments[0] == typeid(double)) 
#         return true;   
#     else if (_arguments[0] == typeid(float)) 
#         return true;  
#     else if (_arguments[0] == typeid(ulong)) 
#         return true; 
#     else if (_arguments[0] == typeid(long)) 
#         return true;   
#     else if (_arguments[0] == typeid(uint)) 
#         return true;  
#     else if (_arguments[0] == typeid(int)) 
#         return true;   
#     else if (_arguments[0] == typeid(ushort)) 
#         return true;   
#     else if (_arguments[0] == typeid(short)) 
#         return true;   
#     else if (_arguments[0] == typeid(ubyte)) 
#     {
#        s.length = 1;
#        s[0]= va_arg!(ubyte)(_argptr);
#        return isNumeric(cast(char[])s);
#     }
#     else if (_arguments[0] == typeid(byte)) 
#     {
#        s.length = 1;
#        s[0] = va_arg!(byte)(_argptr);
#        return isNumeric(cast(char[])s);
#     }
#     else if (_arguments[0] == typeid(ireal))
#         return true;
#     else if (_arguments[0] == typeid(idouble)) 
#         return true;   
#     else if (_arguments[0] == typeid(ifloat)) 
#         return true;  
#     else if (_arguments[0] == typeid(creal))
#         return true;
#     else if (_arguments[0] == typeid(cdouble)) 
#         return true;   
#     else if (_arguments[0] == typeid(cfloat)) 
#         return true;  
#     else if (_arguments[0] == typeid(char))
#     {
#         s.length = 1;
#         s[0] = va_arg!(char)(_argptr);
#         return isNumeric(s);
#     }
#     else if (_arguments[0] == typeid(wchar))
#     {
#         ws.length = 1;
#         ws[0] = va_arg!(wchar)(_argptr);
#         return isNumeric(std.utf.toUTF8(ws));
#     }
#     else if (_arguments[0] == typeid(dchar))
#     { 
#         ds.length =  1;
#         ds[0] = va_arg!(dchar)(_argptr);
#         return isNumeric(std.utf.toUTF8(ds));
#     }
#     //else if (_arguments[0] == typeid(cent)) 
#     //    return true;   
#     //else if (_arguments[0] == typeid(ucent)) 
#     //    return true;  
#     else       
#        return false; 
# }
# 
# unittest
# {
#     writefln( "isNumeric(in char[], bool = false).unittest" );
#     char[] s;
# 
#     // Test the isNumeric(in char[]) function
#     assert(isNumeric("1") == true );
#     assert(isNumeric("1.0") == true );
#     assert(isNumeric("1e-1") == true );
#     assert(isNumeric("12345xxxx890") == false );
#     assert(isNumeric("567L") == true );
#     assert(isNumeric("23UL") == true );
#     assert(isNumeric("-123..56f") == false );
#     assert(isNumeric("12.3.5.6") == false );
#     assert(isNumeric(" 12.356") == false );
#     assert(isNumeric("123 5.6") == false );
#     assert(isNumeric("1233E-1+1.0e-1i") == true );
#  
#     assert(isNumeric("123.00E-5+1234.45E-12Li") == true);
#     assert(isNumeric("123.00e-5+1234.45E-12iL") == false);
#     assert(isNumeric("123.00e-5+1234.45e-12uL") == false);
#     assert(isNumeric("123.00E-5+1234.45e-12lu") == false);
#   
#     assert(isNumeric("123fi") == true);
#     assert(isNumeric("123li") == true);
#     assert(isNumeric("--123L") == false);
#     assert(isNumeric("+123.5UL") == false);
#     assert(isNumeric("123f") == true);
#     assert(isNumeric("123.u") == false);
# 
#     assert(isNumeric(std.string.toString(real.nan)) == true);
#     assert(isNumeric(std.string.toString(-real.infinity)) == true);
#     assert(isNumeric(std.string.toString(123e+2+1234.78Li)) == true);
# 
#     s = "$250.99-";
#     assert(isNumeric(s[1..s.length - 2]) == true);
#     assert(isNumeric(s) == false);
#     assert(isNumeric(s[0..s.length - 1]) == false);
# 
#     // These test calling the isNumeric(...) function
#     assert(isNumeric(1,123UL) == true);
#     assert(isNumeric('2') == true);
#     assert(isNumeric('x') == false);
#     assert(isNumeric(cast(byte)0x57) == false); // 'W'
#     assert(isNumeric(cast(byte)0x37) == true);  // '7'
#     assert(isNumeric(cast(wchar[])"145.67") == true);
#     assert(isNumeric(cast(dchar[])"145.67U") == false);
#     assert(isNumeric(123_000.23fi) == true);
#     assert(isNumeric(123.00E-5+1234.45E-12Li) == true);
#     assert(isNumeric(real.nan) == true);
#     assert(isNumeric(-real.infinity) == true);
# }
# 
# debug( isnumeric )
# {
# int main()
# {
#     writefln("unittest done!");
#     return 0;
# }
# }

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
Jun 01 2005
parent reply "Andrew Fedoniouk" <news terrainformatica.com> writes:
Cool!

David, would it be possible to write also toNumeric ?

Like this:

std.boxer.Box  toNumeric(const char[] s, bool bAllowSep = false)

?

Andrew.






"David L. Davis" <SpottedTiger yahoo.com> wrote in message 
news:d7m0nf$3s0$1 digitaldaemon.com...
 I'd like to share what I've written which may help others in their own D 
 code,
 and wish to contribute this code to Digital Mars D if Walter will accept 
 it. I'm
 not sure exactly which module this code would best fit in if it's 
 accepted,
 whether that would be in the std.string, std.math, or maybe in some a new
 std.misc module.

 But anyway, I found that I needed a isNumeric() function for my variant
 (user-defined) datatype project, and already know I'll find it very useful 
 in
 checking for numeric strings. After creating this code, I decided to scan 
 the
 web for code others might have written for a isNumeric() function and to 
 see if
 I might have missed anything important in my own function. But, to my 
 surprise I
 found that most of them did something that was more of a isDigits() 
 function
 than a isNumeric() function...which I thought was pretty darn odd. Well, I 
 hope
 someone will find this code a tat-bit useful...enjoy! :)

 # /+
 #  ' Source        : isNumeric.d
 #  ' Version       : v0.3
 #  ' Author        : David L. 'SpottedTiger' Davis
 #  ' Date Created  : 31.May.05 Compiled and Tested with dmd v0.125
 #  ' Date Modified : 01.Jun.05 Modified the function to handle the
 #  '               :           imaginary and complex float-point
 #  '               :           datatypes.
 #  '               :
 #  ' Licence       : Public Domain / Contributed to Digital Mars
 #  ' --------------------------------------------------------------
 #  ' To Complie : C:\dmd>dmd mycode.d isnumeric.d
 #  ' To Unittest: C:\dmd>dmd isnumeric.d -debug=isnumeric -unittest
 #  +/
 # module isnumeric;
 #
 # private import std.stdio;  // for writefln();
 # private import std.string; // for tolower()
 # private import std.stdarg; // for argument gathering
 # private import std.utf;    // for toUTF8()
 #
 # /+
 #  ' final bool isNumeric(in char[], in bool = false)
 #  ' ---------------------------------------------------------------
 #  ' [in] char[] s can be formatted in the following ways:
 #  '
 #  ' Integer Whole Number:
 #  ' (for byte, ubyte, short, ushort, int, uint, long, and ulong)
 #  ' ['+'|'-']digit(s)[U|L|UL]
 #  '
 #  ' examples: 123, 123UL, 123L, +123U, -123L
 #  '
 #  ' Floating-Point Number:
 #  ' (for float, double, real, ifloat, idouble, and ireal)
 #  ' ['+'|'-']digit(s)[.][digit(s)][[e-|e+]digit(s)][i|f|L|Li|fi]]
 #  '      or [nan|nani|inf|-inf]
 #  '
 #  ' examples: +123., -123.01, 123.3e-10f, 123.3e-10fi, 123.3e-10L
 #  '
 #  ' (for cfloat, cdouble, and creal)
 #  ' ['+'|'-']digit(s)[.][digit(s)][[e-|e+]digit(s)][+]
 #  '         [digit(s)[.][digit(s)][[e-|e+]digit(s)][i|f|L|Li|fi]]
 #  '      or [nan|nani|nan+nani|inf|-inf]
 #  '
 #  ' examples: nan, -123e-1+456.9e-10Li, +123e+10+456i, 123+456
 #  '
 #  ' [in] bool bAllowSep
 #  ' False by default, but when set to true it will accept the
 #  ' separator characters "," and "_" within the string, but these
 #  ' characters should be stripped from the string before using any
 #  ' of the conversion functions like toInt(), toFloat(), and etc
 #  ' else an error will occur.
 #  '
 #  ' Also please note, that no spaces are allowed within the string
 #  ' anywhere whether it's a leading, trailing, or embedded space(s),
 #  ' thus they too must be stripped from the string before using this
 #  ' function, or any of the conversion functions.
 #  +/
 # final bool isNumeric(in char[] s, in bool bAllowSep = false)
 # {
 #     int    iLen = s.length;
 #     bool   bDecimalPoint = false;
 #     bool   bExponent = false;
 #     bool   bComplex = false;
 #     char[] sx = std.string.tolower(s);
 #     int    j  = 0;
 #     char   c;
 #
 #     //writefln("isNumeric(char[], bool = false) called!");
 #     // Empty string, return false
 #     if (iLen == 0)
 #         return false;
 #
 #     // Check for NaN (Not a Number)
 #     if (sx == "nan" || sx == "nani" || sx == "nan+nani")
 #         return true;
 #
 #     // Check for Infinity
 #     if (sx == "inf" || sx == "-inf")
 #         return true;
 #
 #     // A sign is allowed only in the 1st character
 #     if (sx[0] == '-' || sx[0] == '+')
 #         j++;
 #
 #     for (int i = j; i < iLen; i++)
 #     {
 #         c = sx[i];
 #
 #         // Digits are good, continue checking
 #         // with the next character... ;)
 #         if (c >= '0' && c <= '9')
 #             continue;
 #
 #         // Check for the complex type, and if found
 #         // reset the flags for checking the 2nd number.
 #         else if (c == '+')
 #             if (i > 0)
 #             {
 #                 bDecimalPoint = false;
 #                 bExponent = false;
 #                 bComplex = true;
 #                 continue;
 #             }
 #             else
 #                 return false;
 #
 #         // Allow only one exponent per number
 #         else if (c == 'e')
 #         {
 #             // A 2nd exponent found, return not a number
 #             if (bExponent)
 #                 return false;
 #
 #             if (i + 1 < iLen)
 #             {
 #                 // Look forward for the sign, and if
 #                 // missing then this is not a number.
 #                 if (sx[i + 1] != '-' && sx[i + 1] != '+')
 #                     return false;
 #                 else
 #                 {
 #                     bExponent = true;
 #                     i++;
 #                 }
 #             }
 #             else
 #                 // Ending in "E", return not a number
 #                 return false;
 #         }
 #         // Allow only one decimal point per number to be used
 #         else if (c == '.' )
 #         {
 #             // A 2nd decimal point found, return not a number
 #             if (bDecimalPoint)
 #                 return false;
 #
 #             bDecimalPoint = true;
 #             continue;
 #         }
 #         // Check for ending literal characters: "f,u,l,i,ul,fi,li",
 #         // and wheater they're being used with the correct datatype.
 #         else if (i == iLen - 2)
 #         {
 #             // Integer Whole Number
 #             if (sx[i..iLen] == "ul" &&
 #                (!bDecimalPoint && !bExponent && !bComplex))
 #                 return true;
 #             // Floating-Point Number
 #             else if ((sx[i..iLen] == "fi" || sx[i..iLen] == "li") &&
 #                      (bDecimalPoint || bExponent || bComplex))
 #                 return true;
 #             else if (sx[i..iLen] == "ul" &&
 #                     (bDecimalPoint || bExponent || bComplex))
 #                 return false;
 #             // Could be a Integer or a Float, thus
 #             // all these suffixes are valid for both
 #             else if (sx[i..iLen] == "ul" ||
 #                      sx[i..iLen] == "fi" ||
 #                      sx[i..iLen] == "li")
 #                 return true;
 #             else
 #                 return false;
 #         }
 #         else if (i == iLen - 1)
 #         {
 #             // Integer Whole Number
 #             if ((c == 'u' || c == 'l') &&
 #                 (!bDecimalPoint && !bExponent && !bComplex))
 #                 return true;
 #             // Check to see if the last character in the string
 #             // is the required 'i' character
 #             else if (bComplex)
 #                 if (c == 'i')
 #                     return true;
 #                 else
 #                     return false;
 #             // Floating-Point Number
 #             else if ((c == 'l' || c == 'f' || c == 'i') &&
 #                      (bDecimalPoint || bExponent))
 #                 return true;
 #             // Could be a Integer or a Float, thus
 #             // all these suffixes are valid for both
 #             else if (c == 'l' || c == 'f' || c == 'i')
 #                 return true;
 #             else
 #                 return false;
 #         }
 #         else
 #             // Check if separators are allow
 #             // to be in the numeric string
 #             if (bAllowSep == true && (c == '_' || c == ','))
 #                 continue;
 #             else
 #                 return false;
 #     }
 #
 #     return true;
 # }
 #
 # // Allow any object as a parameter
 # bool isNumeric(...)
 # {
 #     return isNumeric(_arguments, _argptr);
 # }
 #
 # // Check only the first parameter, all others will be ignored.
 # bool isNumeric(TypeInfo[] _arguments, va_list _argptr)
 # {
 #     char[]  s  = "";
 #     wchar[] ws = "";
 #     dchar[] ds = "";
 #
 #     //writefln("isNumeric(...) called!");
 #     if (_arguments.length == 0)
 #         return false;
 #
 #     if (_arguments[0] == typeid(char[]))
 #         return isNumeric(va_arg!(char[])(_argptr));
 #     else if (_arguments[0] == typeid(wchar[]))
 #         return isNumeric(std.utf.toUTF8(va_arg!(wchar[])(_argptr)));
 #     else if (_arguments[0] == typeid(dchar[]))
 #         return isNumeric(std.utf.toUTF8(va_arg!(dchar[])(_argptr)));
 #     else if (_arguments[0] == typeid(real))
 #         return true;
 #     else if (_arguments[0] == typeid(double))
 #         return true;
 #     else if (_arguments[0] == typeid(float))
 #         return true;
 #     else if (_arguments[0] == typeid(ulong))
 #         return true;
 #     else if (_arguments[0] == typeid(long))
 #         return true;
 #     else if (_arguments[0] == typeid(uint))
 #         return true;
 #     else if (_arguments[0] == typeid(int))
 #         return true;
 #     else if (_arguments[0] == typeid(ushort))
 #         return true;
 #     else if (_arguments[0] == typeid(short))
 #         return true;
 #     else if (_arguments[0] == typeid(ubyte))
 #     {
 #        s.length = 1;
 #        s[0]= va_arg!(ubyte)(_argptr);
 #        return isNumeric(cast(char[])s);
 #     }
 #     else if (_arguments[0] == typeid(byte))
 #     {
 #        s.length = 1;
 #        s[0] = va_arg!(byte)(_argptr);
 #        return isNumeric(cast(char[])s);
 #     }
 #     else if (_arguments[0] == typeid(ireal))
 #         return true;
 #     else if (_arguments[0] == typeid(idouble))
 #         return true;
 #     else if (_arguments[0] == typeid(ifloat))
 #         return true;
 #     else if (_arguments[0] == typeid(creal))
 #         return true;
 #     else if (_arguments[0] == typeid(cdouble))
 #         return true;
 #     else if (_arguments[0] == typeid(cfloat))
 #         return true;
 #     else if (_arguments[0] == typeid(char))
 #     {
 #         s.length = 1;
 #         s[0] = va_arg!(char)(_argptr);
 #         return isNumeric(s);
 #     }
 #     else if (_arguments[0] == typeid(wchar))
 #     {
 #         ws.length = 1;
 #         ws[0] = va_arg!(wchar)(_argptr);
 #         return isNumeric(std.utf.toUTF8(ws));
 #     }
 #     else if (_arguments[0] == typeid(dchar))
 #     {
 #         ds.length =  1;
 #         ds[0] = va_arg!(dchar)(_argptr);
 #         return isNumeric(std.utf.toUTF8(ds));
 #     }
 #     //else if (_arguments[0] == typeid(cent))
 #     //    return true;
 #     //else if (_arguments[0] == typeid(ucent))
 #     //    return true;
 #     else
 #        return false;
 # }
 #
 # unittest
 # {
 #     writefln( "isNumeric(in char[], bool = false).unittest" );
 #     char[] s;
 #
 #     // Test the isNumeric(in char[]) function
 #     assert(isNumeric("1") == true );
 #     assert(isNumeric("1.0") == true );
 #     assert(isNumeric("1e-1") == true );
 #     assert(isNumeric("12345xxxx890") == false );
 #     assert(isNumeric("567L") == true );
 #     assert(isNumeric("23UL") == true );
 #     assert(isNumeric("-123..56f") == false );
 #     assert(isNumeric("12.3.5.6") == false );
 #     assert(isNumeric(" 12.356") == false );
 #     assert(isNumeric("123 5.6") == false );
 #     assert(isNumeric("1233E-1+1.0e-1i") == true );
 #
 #     assert(isNumeric("123.00E-5+1234.45E-12Li") == true);
 #     assert(isNumeric("123.00e-5+1234.45E-12iL") == false);
 #     assert(isNumeric("123.00e-5+1234.45e-12uL") == false);
 #     assert(isNumeric("123.00E-5+1234.45e-12lu") == false);
 #
 #     assert(isNumeric("123fi") == true);
 #     assert(isNumeric("123li") == true);
 #     assert(isNumeric("--123L") == false);
 #     assert(isNumeric("+123.5UL") == false);
 #     assert(isNumeric("123f") == true);
 #     assert(isNumeric("123.u") == false);
 #
 #     assert(isNumeric(std.string.toString(real.nan)) == true);
 #     assert(isNumeric(std.string.toString(-real.infinity)) == true);
 #     assert(isNumeric(std.string.toString(123e+2+1234.78Li)) == true);
 #
 #     s = "$250.99-";
 #     assert(isNumeric(s[1..s.length - 2]) == true);
 #     assert(isNumeric(s) == false);
 #     assert(isNumeric(s[0..s.length - 1]) == false);
 #
 #     // These test calling the isNumeric(...) function
 #     assert(isNumeric(1,123UL) == true);
 #     assert(isNumeric('2') == true);
 #     assert(isNumeric('x') == false);
 #     assert(isNumeric(cast(byte)0x57) == false); // 'W'
 #     assert(isNumeric(cast(byte)0x37) == true);  // '7'
 #     assert(isNumeric(cast(wchar[])"145.67") == true);
 #     assert(isNumeric(cast(dchar[])"145.67U") == false);
 #     assert(isNumeric(123_000.23fi) == true);
 #     assert(isNumeric(123.00E-5+1234.45E-12Li) == true);
 #     assert(isNumeric(real.nan) == true);
 #     assert(isNumeric(-real.infinity) == true);
 # }
 #
 # debug( isnumeric )
 # {
 # int main()
 # {
 #     writefln("unittest done!");
 #     return 0;
 # }
 # }

 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 

Jun 02 2005
next sibling parent reply Derek Parnell <derek psych.ward> writes:
On Thu, 2 Jun 2005 15:26:27 -0700, Andrew Fedoniouk wrote:

 Cool!
 
 David, would it be possible to write also toNumeric ?
 
 Like this:
 
 std.boxer.Box  toNumeric(const char[] s, bool bAllowSep = false)

I just wrote one of those a couple of days ago. Its a part of a new application I'm writing but I guess I can split it out ... give me a few moments ... -- Derek Melbourne, Australia 3/06/2005 8:57:45 AM
Jun 02 2005
parent reply Derek Parnell <derek psych.ward> writes:
Content-type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit

On Fri, 3 Jun 2005 08:59:41 +1000, Derek Parnell wrote:

 On Thu, 2 Jun 2005 15:26:27 -0700, Andrew Fedoniouk wrote:
 
 Cool!
 
 David, would it be possible to write also toNumeric ?
 
 Like this:
 
 std.boxer.Box  toNumeric(const char[] s, bool bAllowSep = false)

I just wrote one of those a couple of days ago. Its a part of a new application I'm writing but I guess I can split it out ... give me a few moments ...

Here is my version attached ;-) real TextToNumber( dchar[] pText, out int pStopPosn, bool pNotify = true); Hope somebody finds it useful. -- Derek Melbourne, Australia 3/06/2005 10:32:49 AM
Jun 02 2005
next sibling parent reply "Kris" <fu bar.com> writes:
Cool!

Mango.format has similar stuff for formatting and parsing numbers: e.g.
http://svn.dsource.org/projects/mango/trunk/mango/format/Double.d

There's also a more powerful version using David Gay's dtoa.c code. You
really should take a look at what that C file does ~ it's kinda'
frightening!

http://svn.dsource.org/projects/mango/trunk/mango/format/dtoa.c
http://svn.dsource.org/projects/mango/trunk/mango/format/DGDouble.d

- Kris


"Derek Parnell" <derek psych.ward> wrote in message
news:bo1091wvq352$.1noqjnreoaasw$.dlg 40tude.net...
 On Fri, 3 Jun 2005 08:59:41 +1000, Derek Parnell wrote:

 On Thu, 2 Jun 2005 15:26:27 -0700, Andrew Fedoniouk wrote:

 Cool!

 David, would it be possible to write also toNumeric ?

 Like this:

 std.boxer.Box  toNumeric(const char[] s, bool bAllowSep = false)

I just wrote one of those a couple of days ago. Its a part of a new application I'm writing but I guess I can split it out ... give me a few moments ...

Here is my version attached ;-) real TextToNumber( dchar[] pText, out int pStopPosn, bool pNotify =

 Hope somebody finds it useful.

 -- 
 Derek
 Melbourne, Australia
 3/06/2005 10:32:49 AM

Jun 02 2005
parent reply pragma <pragma_member pathlink.com> writes:
In article <d7odh0$2mv2$1 digitaldaemon.com>, Kris says...
Cool!

Mango.format has similar stuff for formatting and parsing numbers: e.g.
http://svn.dsource.org/projects/mango/trunk/mango/format/Double.d

There's also a more powerful version using David Gay's dtoa.c code. You
really should take a look at what that C file does ~ it's kinda'
frightening!

http://svn.dsource.org/projects/mango/trunk/mango/format/dtoa.c
http://svn.dsource.org/projects/mango/trunk/mango/format/DGDouble.d

- Kris

[reading dtoa.c] "kinda' frigtening" doesn't even begin to describe it. Not only am I reminded of why I switched to D, but I actually feel a touch queasy now. Here's to cleaner solutions and better looking code. - EricAnderton at yahoo
Jun 03 2005
parent reply kris <fu bar.org> writes:
pragma wrote:
 In article <d7odh0$2mv2$1 digitaldaemon.com>, Kris says...
 
Cool!

Mango.format has similar stuff for formatting and parsing numbers: e.g.
http://svn.dsource.org/projects/mango/trunk/mango/format/Double.d

There's also a more powerful version using David Gay's dtoa.c code. You
really should take a look at what that C file does ~ it's kinda'
frightening!

http://svn.dsource.org/projects/mango/trunk/mango/format/dtoa.c
http://svn.dsource.org/projects/mango/trunk/mango/format/DGDouble.d

- Kris

[reading dtoa.c] "kinda' frigtening" doesn't even begin to describe it. Not only am I reminded of why I switched to D, but I actually feel a touch queasy now. Here's to cleaner solutions and better looking code. - EricAnderton at yahoo

First time I read through dtoa.c, I was about half way through and thinking "egad! what the feck?" when up pops a comment in the code saying "Now, here's the difficult stuff" ... I knew, at that point, that I was completely out of my depth.
Jun 03 2005
parent Sean Kelly <sean f4.ca> writes:
In article <d7pvni$rsr$1 digitaldaemon.com>, kris says...
First time I read through dtoa.c, I was about half way through and 
thinking "egad! what the feck?" when up pops a comment in the code 
saying "Now, here's the difficult stuff" ... I knew, at that point, that 
I was completely out of my depth.

The best part about this profession is being hired to maintain code like that. Perhaps back when that stuff was actually written the few CPU cycles it saved over a readable design were actually important ;) Sean
Jun 03 2005
prev sibling parent reply "Andrew Fedoniouk" <news terrainformatica.com> writes:
"Derek Parnell" <derek psych.ward> wrote in message 
news:bo1091wvq352$.1noqjnreoaasw$.dlg 40tude.net...
 On Fri, 3 Jun 2005 08:59:41 +1000, Derek Parnell wrote:

 On Thu, 2 Jun 2005 15:26:27 -0700, Andrew Fedoniouk wrote:

 Cool!

 David, would it be possible to write also toNumeric ?

 Like this:

 std.boxer.Box  toNumeric(const char[] s, bool bAllowSep = false)

I just wrote one of those a couple of days ago. Its a part of a new application I'm writing but I guess I can split it out ... give me a few moments ...

Here is my version attached ;-) real TextToNumber( dchar[] pText, out int pStopPosn, bool pNotify = true); Hope somebody finds it useful.

Nice, Derek, One thought: to have returning value as box allows: 1) to detect was it value at all; 2) to select the most compact storage form. 3) to be more precise - casting real to int is always something from fuzzy logic field. Just my guess. Andrew.
 -- 
 Derek
 Melbourne, Australia
 3/06/2005 10:32:49 AM 

Jun 02 2005
parent Derek Parnell <derek psych.ward> writes:
On Thu, 2 Jun 2005 21:33:45 -0700, Andrew Fedoniouk wrote:


[snip]
 One thought:
 
 to have returning value as box allows:
 
 1) to detect was it value at all;
 2) to select the most compact storage form.
 3) to be more precise - casting real to int is always something from
     fuzzy logic field.

This was ported from another language and before the boxer module was available. I'll have go at implementing your suggestion though ... wish me luck ;-) -- Derek Melbourne, Australia 3/06/2005 3:01:16 PM
Jun 02 2005
prev sibling next sibling parent David L. Davis <SpottedTiger yahoo.com> writes:
In article <d7o12k$2dv4$1 digitaldaemon.com>, Andrew Fedoniouk says...
Cool!

David, would it be possible to write also toNumeric ?

Like this:

std.boxer.Box  toNumeric(const char[] s, bool bAllowSep = false)

?

Andrew.

Andrew, here's what I came up with so far...what do you think? (Note: that this uses the isNumeric.d code as an import) # /+ # ' Source : toNumeric.d - Convert a numeric string into a boxed numeric # ' Author : David L. 'SpottedTiger' Davis # ' Created: 02.Jun.05 # ' License: Public Domain # ' ----------------------------------------------------------- # ' Note : When using the std.boxer module, always compile # ' with the "-release" dmd commandline switch, # ' otherwise you'll get a linker error. # ' ----------------------------------------------------------- # ' To Compile: dmd mycode.d tonumeric.d isnumeric.d -release # +/ # private import std.stdio; # private import std.boxer; // now in D v0.124 # private import std.conv; # private import isnumeric; # # Box toNumeric( in char[] s, in bool bAllowSep = false) # { # Box boxx; # char[] sx = std.string.strip(s); # int iLen = s.length; # bool bComplex = false; # bool bNeg = false; # bool bExponent = false; # bool bISuffix = false; # bool bInt = true; # int j = 0; # char c; # long l = 0L; # ulong ul = 0UL; # real r = real.nan; # //ireal ir = ireal.nan; # //creal cr = creal.nan; # # // Check first for NaN and Infinity # if (sx == "nan") # { boxx = box(real.nan); return boxx; } # else if (sx == "inf") # { boxx = box(real.infinity); return boxx; } # else if (sx == "-inf") # { boxx = box(-real.infinity); return boxx; } # else if (sx == "nani") # { boxx = box(ireal.nan); return boxx; } # else if (sx == "nan+nani") # { boxx = box(creal.re.nan+creal.im.nan); return boxx; } # # // If valid numeric string, set flags before boxing, # // else throw an Exception that its not a numeric string. # if (isNumeric(sx, bAllowSep)) # { # if (sx[0] == '+') # j++; # # // Is a negative number # else if (sx[0] == '-') # { # j++; # bNeg = true; # } # # for (int i = j; i < s.length; i++) # { # c = s[i]; # # // Decimal found, number is a floating-point # if (c == '.') # bInt = false; # else if (c == 'e' || c == 'E') # { # i++; # // if two exponents found, then # // this is a complex float # if (bExponent) # bComplex = true; # # bExponent = true; # bInt = false; # continue; # } # // A single plus-sign found after # // the first position, makes this a # // complex float. # else if (c == '+') # bComplex = true; # else if (c == 'i' || c == 'I') # bISuffix = true; # else {} # } # } # else # { # throw new Exception("Error in toNumeric(in char[], " ~ # "in bool = false), the first parameter " ~ # s ~ " is not a numeric string!"); # } # # // Remove Separators # if (bAllowSep) # { # sx = std.string.replace(sx, "_", ""); # sx = std.string.replace(sx, ",", ""); # } # # // Remove suffixes other than 'i' before # // calling the conversion functions # c = sx[sx.length - 1]; # if (c == 'f' || c == 'F' || c == 'l' || # c == 'L' || c == 'u' || c == 'U') # sx.length = s.length - 1; # # c = sx[sx.length - 1]; # if (c == 'f' || c == 'F' || c == 'l' || # c == 'L' || c == 'u' || c == 'U') # sx.length = s.length - 1; # # // Positive Whole Number # if (bInt && !bNeg) # { # //writefln("Unsigned Int"); # ul = std.conv.toUlong(sx); # if (ul <= ubyte.max) # boxx = box(cast(ubyte)ul); # else if (ul <= ushort.max) # boxx = box(cast(ushort)ul); # else if (ul <= uint.max) # boxx = box(cast(uint)ul); # else # boxx = box(ul); # } # // Negative Whole Numer # else if (bInt && bNeg) # { # //writefln("Signed Int"); # l = std.conv.toLong(sx); # if (l <= byte.max) # boxx = box(cast(byte)l); # else if (l <= short.max) # boxx = box(cast(short)l); # else if (l <= int.max) # boxx = box(cast(int)l); # else # boxx = box(cast(long)l); # } # // Regular Floating-Point Number # else if (!bISuffix && !bComplex) # { # //writefln("Regular Float"); # r = std.conv.toReal(sx); # if (r <= float.max) # boxx = box(cast(float)r); # else if (r <= double.max) # boxx = box(cast(double)r); # else # boxx = box(r); # } # /******************************************************/ # /* ** Walter is still working on putting these in ** */ # /******************************************************/ # // Imaginary Floating-Point Number # else if (bISuffix && !bComplex) # { # //writefln("Imaginary Float"); # # //ir = std.conv.toIreal(sx); # //if (ir <= ifloat.max) # // boxx = box(cast(ifloat)ir); # //else if (ir <= idouble.max) # // boxx = box(cast(idouble)ir); # //else # // boxx = box(ir); # # //** Temp fix until the toIreal() is ready in std.conv ** # sx = sx[0..sx.length - 2]; # r = std.conv.toReal(sx); # if (r <= float.max) # boxx = box(cast(ifloat)(r * 1.0i)); # else if (r <= double.max) # boxx = box(cast(idouble)(r * 1.0i)); # else # boxx = box(cast(ireal)(r * 1.0i)); # } # // Complex Floating-Point Number # /+ # else if (bComplex) # { # //writefln("Complex Float"); # //cr = std.conv.toCreal(sx); # //boxx = box(cr); # } # +/ # else # { # //writefln("Unknown"); # throw new Exception("Error in toNumeric(in char[], " ~ # "in bool = false), the first parameter " ~ # s ~ " is not a numeric string!"); # } # # return boxx; # } # # void main() # { # Box wx; # # wx = toNumeric("123"); # writefln("unbox!(uint)(wx)=%d", unbox!(uint)(wx)); # # wx = toNumeric("-12L"); # writefln("unbox!(long)(wx)=%8d", unbox!(long)(wx)); # # wx = toNumeric("1.234"); # writefln("unbox!(double)(wx)=%8.3f", unbox!(double)(wx)); # # wx = toNumeric("1.234fi"); # writefln("unbox!(ifloat)(wx=%8.3f", unbox!(ifloat)(wx)); # # wx = toNumeric("1.234e+12"); # writefln("unbox!(float)(wx)=%8.4g", unbox!(float)(wx)); # # # //Can't do until toCreal() is ready in std.conv # //wx = toNumeric("1.234e+12+345.4e+34i"); # //writefln("cr=%g", creal.re.nan+creal.im.nan); # } Output: ----------------- C:\dmd>dmd tonumeric.d isNumeric.d -release C:\dmd\bin\..\..\dm\bin\link.exe tonumeric+isNumeric,,,user32+kernel32/noi; C:\dmd>tonumeric unbox!(uint)(wx)=123 unbox!(long)(wx)=-12 unbox!(double)(wx)= 1.234 unbox!(ifloat)(wx= 1.234 unbox!(float)(wx)=1.234e+12 C:\dmd> 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
Jun 02 2005
prev sibling parent David L. Davis <SpottedTiger yahoo.com> writes:
In article <d7o12k$2dv4$1 digitaldaemon.com>, Andrew Fedoniouk says...
Cool!

David, would it be possible to write also toNumeric ?

Like this:

std.boxer.Box  toNumeric(const char[] s, bool bAllowSep = false)

?

Andrew.

Here's a working copy! My first one I stayed up too late working on it and I made a few mistakes...which they're all fixed in this version. The nice thing about this code, is that it uses Phobos' builded in std.boxer and std.conv functions to do its work, which are already within the runtime library. Except of course for the isNumeric() function which can be found at the begnning of this thread. Well, I hope this does the trick...but it will be kool to see what others will come up with! ;) # /+ # ' Source : toNumeric.d - Convert a string into a boxed numeric # ' Version : v0.2 Beta # ' Author : David L. 'SpottedTiger' Davis # ' Created : 02.Jun.05: Compiled with dmd v0.125 # ' Modified: 03.Jun.05: Corrected a number of issues, # ' : and added the complex floats. # ' License : Public Domain # ' ----------------------------------------------------------- # ' Note : When using the std.boxer module, always compile # ' with the "-release" dmd commandline switch, # ' otherwise you'll get a linker error. # ' ----------------------------------------------------------- # ' To Compile: dmd mycode.d tonumeric.d isnumeric.d -release # +/ # private import std.stdio; # private import std.boxer; # private import std.string; # private import std.conv; # private import isnumeric; # # Box toNumeric( in char[] s, in bool bAllowSep = false) # { # Box boxx; # char[] sx = std.string.strip(s); # char[] s1 = ""; # char[] s2 = ""; # int iLen = s.length; # bool bComplex = false; # bool bNeg = false; # bool bExponent = false; # bool bISuffix = false; # bool bInt = true; # int j = 0; # char c; # long l = 0L; # ulong ul = 0UL; # real r1 = real.nan; # real r2 = real.nan; # //ireal ir = ireal.nan; # creal cr = creal.nan; # # // Check first for NaN and Infinity # if (sx == "nan") # { boxx = box(float.nan); return boxx; } # else if (sx == "inf") # { boxx = box(float.infinity); return boxx; } # else if (sx == "-inf") # { boxx = box(-float.infinity); return boxx; } # else if (sx == "nani") // || sx == "0i") # { boxx = box(ifloat.nan); return boxx; } # else if (sx == "nan+nani" || sx == "nan+0i") # { boxx = box(cfloat.re.nan+cfloat.im.nan); return boxx; } # # // If a valid numeric string, set flags before boxing, # // else throw an Exception if its not a numeric string. # if (isNumeric(sx, bAllowSep)) # { # if (sx[0] == '+') # j++; # # // Is a negative number # else if (sx[0] == '-') # { # j++; # bNeg = true; # } # # for (int i = j; i < s.length; i++) # { # c = s[i]; # # // Decimal found, number is a floating-point # if (c == '.') # bInt = false; # else if (c == 'e' || c == 'E') # { # i++; # // if two exponents found, then # // this is a complex float # if (bExponent) # bComplex = true; # # bExponent = true; # bInt = false; # continue; # } # // A single plus-sign found after # // the first position, makes this a # // complex float. # else if (c == '+') # { # bComplex = true; # bInt = false; # } # else if (c == 'i' || c == 'I') # { # bISuffix = true; # bInt = false; # } # //else {} # } # } # else # { # throw new Exception("Error in toNumeric(in char[], " ~ # "in bool = false), the first parameter " ~ # s ~ " is not a numeric string!"); # } # # // Remove Separators that may exist, # // if bAllowSep was set to true # if (bAllowSep) # { # sx = std.string.replace(sx, "_", ""); # sx = std.string.replace(sx, ",", ""); # } # # // Set to sx's current length # iLen = sx.length; # # // Remove suffixes other than 'i' before calling # // the conversion functions, else an error with occur. # for (int i = sx.length - 2; i < sx.length; i++) # { # c = sx[i]; # if (c == 'f' || c == 'F' || c == 'l' || # c == 'L' || c == 'u' || c == 'U' || # c == 'I' || c == 'i') # iLen--; # } # # //writefln("sx=\"%s\", bNeg=%b, bInt=%b, bISuffix=%b, bComplex=%b", # // sx, bNeg, bInt, bISuffix, bComplex); # # // Adjust sx's length to iLen # sx.length = iLen; # # // Positive Whole Number # if (bInt && !bNeg) # { # //writefln("Unsigned Int"); # ul = std.conv.toUlong(sx); # if (ul <= ubyte.max) # boxx = box(cast(ubyte)ul); # else if (ul <= ushort.max) # boxx = box(cast(ushort)ul); # else if (ul <= uint.max) # boxx = box(cast(uint)ul); # else # boxx = box(ul); # } # // Negative Whole Numer # else if (bInt && bNeg) # { # //writefln("Signed Int"); # l = std.conv.toLong(sx); # if (l >= byte.min && l <= byte.max) # boxx = box(cast(byte)l); # else if (l >= short.min && l <= short.max) # boxx = box(cast(short)l); # else if (l >= int.min && l <= int.max) # boxx = box(cast(int)l); # else # boxx = box(cast(long)l); # } # // Regular Floating-Point Number # else if (!bISuffix && !bComplex) # { # //writefln("Regular Float"); # r1 = std.conv.toReal(sx); # if (r1 >= float.min && r1 <= float.max) # boxx = box(cast(float)r1); # else if (r1 >= double.min && r1 <= double.max) # boxx = box(cast(double)r1); # else # boxx = box(r1); # } # /*************************************************/ # /* ** Walter still working on putting in the ** */ # /* ** toIfloat() thru toCfloat() functions. ** */ # /*************************************************/ # // Imaginary Floating-Point Number # else if (bISuffix && !bComplex) # { # //writefln("Imaginary Float"); # # //ir = std.conv.toIreal(sx); # //if (ir <= ifloat.max) # // boxx = box(cast(ifloat)ir); # //else if (ir <= idouble.max) # // boxx = box(cast(idouble)ir); # //else # // boxx = box(ir); # # //** A temp fix until the toIreal() is ready in std.conv ** # r1 = std.conv.toReal(sx); # if (r1 >= float.min && r1 <= float.max) # boxx = box(cast(ifloat)(r1 * 1.0i)); # else if (r1 >= double.min && r1 <= double.max) # boxx = box(cast(idouble)(r1 * 1.0i)); # else # boxx = box(cast(ireal)(r1 * 1.0i)); # } # // Complex Floating-Point Number # else if (bComplex) # { # //writefln("Complex Float"); # //cr = std.conv.toCreal(sx); # //boxx = box(cr); # # //** A temp fix until the toCreal() is ready in std.conv ** # splitComplexStrings(sx, s1, s2); # //writefln("sx=\"%s\", s1=\"%s\", s2=\"%s\"", sx, s1, s2); # r1 = toReal(s1); # r2 = toReal(s2); # cr = cast(creal)(r1 + (r2 * 1.0i)); # boxx = box(cr); # } # else # { # //writefln("Unknown"); # throw new Exception("Error in toNumeric(in char[], " ~ # "in bool = false), the first parameter " ~ # s ~ " is not a numeric string!"); # } # # return boxx; # } # # void main() # { # Box wx; # # wx = toNumeric("123456"); # writefln("unbox!(uint)(wx)=%d", unbox!(uint)(wx)); # # wx = toNumeric("-124599"); # writefln("unbox!(long)(wx)=%8d", unbox!(long)(wx)); # # wx = toNumeric("1.234"); # writefln("unbox!(double)(wx)=%8.3f", unbox!(double)(wx)); # # wx = toNumeric("1.234fi"); # writefln("unbox!(ifloat)(wx)=%g", unbox!(ifloat)(wx)); # # wx = toNumeric("1.234e+12"); # writefln("unbox!(float)(wx)=%8.4g", unbox!(float)(wx)); # # wx = toNumeric("1.234e+12+345.4e+34i"); # writefln("unbox!(creal)(wx)=%g", unbox!(creal)(wx)); # # wx = toNumeric("nan+nani"); # writefln("unbox!(creal)(wx)=%g", unbox!(creal)(wx)); # } # # /+ # ' Splits a complex floats (cfloat, cdouble, and creal) into two workable strings. # ' Grammar: # ' (for cfloat, cdouble, and creal) # ' ['+'|'-']digit(s)[.][digit(s)][[e-|e+]digit(s)][+] # ' [digit(s)[.][digit(s)][[e-|e+]digit(s)][i|f|L|Li|fi]] # ' or [nan|nani|nan+nani|inf|-inf] # ' # ' creal Range: from 3.362103E-4932+3.362103E-4932i (min) # ' to 1.189731E+4932+1.189731E+4932i (max) # +/ # bool splitComplexStrings(in char[] s, out char[] s1, out char[] s2) # { # char[] sx = s; # int iLen = s.length; # int plus = 0; # # s1 = ""; # s2 = ""; # # if (!iLen) # throw new Exception("spiitComplexStrings(): input string is an empty string."); # # if (iLen >= 2) # { # sx = std.string.tolower(s); # // When "nan" or "nani" just return them. # if (s == "nan" || s == "nani" || s == "nan+nani") # { s1 = "nan"; s2 = "nani"; return 1; } # # if (s == "inf") # { s1 = "inf"; s2 = "infi"; return 1; } # # if (s == "-inf") # { s1 = "-inf"; s2 = "-infi"; return 1; } # } # # // Split the original string out into two strings. # for (int i = 1; i < iLen; i++) # if ((sx[i - 1] != 'e' && sx[i - 1] != 'E') && sx[i] == '+') # { # s1 = s[0..i]; # if (i + 1 < iLen - 1) # s2 = s[i + 1..iLen]; // - 1]; # else # s2 = "0e+0i"; # # break; # } # # // Handle the case when there's only a single value # // to work with, and set the other string to zero. # if (!s1.length) # { s1 = sx; s2 = "0e+0i"; } # # //writefln( "getComplexStrings() s=\"%s\", s1=\"%s\", s2=\"%s\", len=%d", # // s, s1, s2, len ); # # return true; # } Output: ---------- C:\dmd>dmd tonumeric.d isnumeric.d -release C:\dmd\bin\..\..\dm\bin\link.exe tonumeric+isnumeric,,,user32+kernel32/noi; C:\dmd>tonumeric unbox!(uint)(wx)=123456 unbox!(long)(wx)= -124599 unbox!(double)(wx)= 1.234 unbox!(ifloat)(wx)=1.234 unbox!(float)(wx)=1.234e+12 unbox!(creal)(wx)=1.234e+12+3.454e+36i unbox!(creal)(wx)=nan+0i C:\dmd> 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
Jun 03 2005