Noteupdated based on comment feedback: Some (most?) compilers expect two argument versions for the strtol and strtod. The code below was written on a Windows system which prefers three arguments (including a base argument). link
One more approach, using LibraryLink. Create a C file called strto.ccpp as follows:
#include <stdlib.h> #include <stdio.h><cstdlib> #include "WolframLibrary.h" EXTERN_C DLLEXPORT int wolfram_strtol(WolframLibraryData libData, mint Argc, MArgument *Args, MArgument Res) { char *string; mint base; mint result; string = MArgument_getUTF8String(Args[0]); base = MArgument_getInteger(Args[1]); result = strtol(string, NULL, base); MArgument_setInteger(Res,result); return LIBRARY_NO_ERROR; } EXTERN_C DLLEXPORT int wolfram_strtod(WolframLibraryData libData, mint Argc, MArgument *Args, MArgument Res) { char *string; mint base; mreal result; string = MArgument_getUTF8String(Args[0]); base = MArgument_getInteger(Args[1]); result = strtod(string, NULL, base); MArgument_setReal(Res,result); return LIBRARY_NO_ERROR; } This is a very thin wrapper for the CC++ strtol and strtod standard library functions.
Needs["CCompilerDriver`"]; lib = CreateLibrary[{"wolfram_strto.c"cpp"}, "wolfram_strto"] strtol = LibraryFunctionLoad[lib, "wolfram_strtol", {"UTF8String", Integer}, Integer]; strtod = LibraryFunctionLoad[lib, "wolfram_strtod", {"UTF8String", Integer}, Real]; strtod["10e4", 10]strtod["10e4"] strtod[#, 0] &strtod /@ {"3.14159", "3.14159e-02", "3.14159e+02", "1.23e-5", "1E6", "1.734E-003", "2.12e1"} The second argument '0' to strtod signifies automatic base detection.
This should return 10995 (e.g. same as 16^^2AF3)
One benefit strtod has over Internal`StringToDouble is that the latter can not do hexadecimal numbers:
Internal`StringToDouble["0x6400"] This returns 6400, which is the (wrong) decimal interpretation.
strings = ToString @ Row[ RandomChoice /@ {{"-", ""}, {#}, {"e"}, {"-", ""}, Range@12}] & /@ RandomReal[{0, 10}, 15000] First@AbsoluteTiming[strtod[#, 0]First@AbsoluteTiming[ &strtod /@ strings] Internal`StringToDouble["1e4000"] strtod["1e4000", 0]strtod["1e4000"]