How do you convert a string containing a number in C scientific notation to a Mathematica number?
I think probably the cleanest way to do this (at least, if you have only a single string, or are faced with a separate string for each number you wish to convert as a result of some other process) is to use the undocumented function Internal`StringToDouble
, i.e.:
s = "1.23e-5";
Internal`StringToDouble[s]
which gives:
0.0000123
However, if you are trying to convert many such numbers at once, the standard, documented methods (Import
, Read
, etc.), are likely to represent better approaches.
s = "1.23e-5"
# &[Read[#, Number], Close@#]&[ StringToStream@s ]
Which is not as good as what you started with. Note that it is important to close the stream.
Szabolcs says this is difficult to read. That was surely not my intention. You could also write it verbosely like this:
fromC =
Module[{output, stream},
stream = StringToStream[#];
output = Read[stream, Number];
Close[stream];
output
] &;
fromC[s]
On version 7 Internal`StringToDouble
fails on long strings, and fails to recognize exponents:
Internal`StringToDouble["3.1415926535897932385"]
Internal`StringToDouble /@ {"3.14159", "3.14159e-02", "3.14159e+02"}
$Failed["Bignum"] {3.14159, 3.14159, 3.14159}
This sent me looking for another way to convert numeric strings. Using Trace
on ImportString
I found another internal function that does what I need: System`Convert`TableDump`ParseTable
.
Being an internal function is it not error tolerant and if fed bad arguments it will crash the kernel. The syntax is as follows:
System`Convert`TableDump`ParseTable[
table,
{{pre, post}, {neg, pos}, dot},
False
]
table : table of strings, depth = 2; need not be rectangular. pre : List of literal strings to ignore if preceding the digits (only first match tried). post : List of literal strings to ignore if following the digits (only first match tried). neg : literal string to interpret a negative sign (`-`). pos : literal string to interpret a positive sign (`+`). dot : literal string to interpret as decimal point.
(Using True
in place of False
causes a call to System`Convert`TableDump`TryDate
that I do not yet understand.)
Example:
System`Convert`TableDump`ParseTable[
{{"-£1,234.141592653589793e+007"}, {"0.97¢", "140e2kg"}},
{{{"£"}, {"kg", "¢"}}, {"-", "+"}, "."},
False
]
{{-1.2341415926535898*^10}, {0.97, 14000.}}