FromDigits only works for integer strings. What's its real-number analogue?
2 Answers
This is a good question, but unfortunately there doesn't seem to be a perfect solution.
You can use
ToExpression
, e.g.ToExpression["1.23"]
. But: (1) this gives no error checking (2) it's a serious security risk if you obtain the string from users (and it can go things go haywire in general if the string comes from an unknown source)Internal`StringToDouble
can parse floating point numbers in C format. It accepts both"1.24"
and"12.4e-1"
. But: (1) is is undocumented so there are no guarantees of compatibility or that it won't crash your kernel (2) it still doesn't offer error checkingIn version 10, there's
Interpreter
. For example,Interpreter["Number"]["1.24"]
. It is flexible, supports both1.23e4
and1.23*10^4
. It provides error checking. It's probably the best choice. But: It is very slow, and unsuitable for parsing a long list of numbers. Parsing only 1000 numbers takes a full second on my i7 machine. It doesn't make it possible to implement e.g. a CSV parser in Mathematica.
So none of these is a perfect solution. There's always the choice to implement your own in C if you need all of speed, reliability and error checking. But it takes a lot of work to do this.
Thanks to @chuy in the chatroom, here's a way to make ToExpression
safer:
toNum[e_String] := Replace[
Quiet@ToExpression[e, InputForm, HoldComplete],
{HoldComplete[n : (_Integer | _Real)] :> n, _ -> $Failed}
]
This is safer than using ToExpression
alone and much faster than Interpreter["Number"]
. It handles numbers that follow the Mathematica syntax, so keep in mind that strange looking things such as toNum["16^^abc"]
will work.
-
$\begingroup$ I concur on the slowness of Interpreter. It was probably developed to parse WolframAlpha input, i.e., just a single line. It's totally and utterly useless for any serious big data project. $\endgroup$ Apr 1, 2015 at 7:44
Here’s first code line of Stephen Wolfram’s Pi or Pie?! Celebrating Pi Day of the Century blog post:
PiString = StringDrop[ToString[N[Pi, 10^2]], {2}];
Stephen converted the first 10 million digits of π to a string without a decimal point, but I’ve taken just the first 100 digits. The real number analogue of FromDigits would be:
PiApproximate = FromDigits[PiString]/10^(10^2 - 1);
Convert this approximate π into a string:
PiStringApproximate = StringDrop[ToString[N[PiApproximate, 10^2]], {2}];
and yes, it exactly matches the real thing:
PiStringApproximate === PiString
-
$\begingroup$ I believe the question is: How can we parse floating point numbers? This doesn't answer that. $\endgroup$– SzabolcsMar 31, 2015 at 20:25
-
$\begingroup$ @Szabolcs Where do I find this chat that you mention in your answer? $\endgroup$ Apr 1, 2015 at 0:52
-
$\begingroup$ Click the StackExchange logo at the top of the page, and click chat. Or click here: Mathematica Chat. Unlike the main site, the chat is free, any topic goes. $\endgroup$– SzabolcsApr 1, 2015 at 3:53
-
$\begingroup$ For the interested reader's benefit, here's the @chuy chat link. $\endgroup$ Apr 1, 2015 at 15:35
RealDigits[ToExpression["1234.234532"]]
gives{{1, 2, 3, 4, 2, 3, 4, 5, 3, 2, 0, 0, 0, 0, 0, 0}, 4}
$\endgroup$ToExpression
or someInterpreter
, orInternal`StringToDouble
$\endgroup$ImportString["1.234 5.678e2", "Table"]
might do the sort of thing that you want. $\endgroup$