2
$\begingroup$
ToExpression["9.0E-03"]

interprets the string as

9*e - 3

instead of what I am expecting:

0.009

How can I convert the expression to fortran notation?

$\endgroup$
3

2 Answers 2

7
$\begingroup$

You can use ImportString, with the "Table" or "List" argument. See the documentation for details.

ImportString["9.0E-03", "Table"]

(* {{0.009}} *)

or

ImportString["9.0E-03", "List"]

(* {0.009} *)
$\endgroup$
2
  • $\begingroup$ thank you! I'm a bit puzzled though with Mathematica's architecture: why is it a separate function and moreover contains Import in its title? $\endgroup$ May 23, 2014 at 7:30
  • 1
    $\begingroup$ ImportString takes a String as argument and provides the same output as Import, which takes a file as Argument. $\endgroup$ May 23, 2014 at 7:37
7
$\begingroup$

The given above answer is correct, however if you are not against using undocumented functions, then

Internal`StringToDouble["9.0E-03"]

is much faster.

To demonstrate the speedup, first generate some fake data

heads = ToString /@ 
    RandomReal[{1.0000, 9.9999}, 100000, WorkingPrecision -> 5] // Quiet;
exp = ConstantArray["E-", 100000];
tails = ToString /@ RandomInteger[{0, 9}, 100000];
strings = MapThread[StringJoin, {heads, exp, tails}]
lines = ExportString[strings, "List"];

So strings is a list of strings in the form of "1.3452E-5" and lines is one big string with each number in the same format separated with a newline. The two options are:

Internal`StringToDouble /@ strings // AbsoluteTiming // Short
{0.0408109,{2.0525*10^-9,7.983*10^-7,<<99997>>,0.000099743}}

and

ImportString[lines, "List"] // AbsoluteTiming // Short
{0.626226,{2.0525*10^-9,7.983*10^-7,<<99997>>,0.000099743}}

If you have the choice of input format (list of strings or strings with newlines), then Internal`StringToDouble is 15 times faster.

Finally, ReadList is useful to juggle the string formats. First option:

Internal`StringToDouble /@ ReadList[StringToStream[lines], String] // AbsoluteTiming // Short
{0.0808349,{2.0525*10^-9,<<99998>>,0.000099743}}

That is to say, ReadList[StringToStream[lines], String] is much faster in converting the string with linebreaks to a list of strings than ImportString[lines, "List"]. Additionally, to test everything "for real":

Export["test.dat", lines, "String"] (* this takes a while, but we're 
                                       planning to import, not export *)
Internal`StringToDouble /@ ReadList["test.dat", String] // AbsoluteTiming // Short
{0.0769682,{2.0525*10^-9,7.983*10^-7,<<99997>>,0.000099743}}
$\endgroup$
1
  • $\begingroup$ If importing a file with 5 numbers per row and ~11K rows (so, 5500 calls), this is the only way to go (with respect to answers on this page). Though the other answer does work and is feasible for small computations. +1 $\endgroup$
    – Ghersic
    Oct 11, 2017 at 0:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.