3

FromDigits only works for integer strings. What's its real-number analogue?

user13253
  • 8,666
  • 2
  • 42
  • 65
  • 1
    RealDigits? as in RealDigits[ToExpression["1234.234532"]] gives {{1, 2, 3, 4, 2, 3, 4, 5, 3, 2, 0, 0, 0, 0, 0, 0}, 4} – Nasser Jan 26 '15 at 04:53
  • What's the format of the input? If its a simple string, ToExpression or some Interpreter, or Internal`StringToDouble – Rojo Jan 26 '15 at 06:06
  • Internal`StringToDouble is fine. ToExpression is too dangerous in general Interpreter is not backwards compatible. – user13253 Jan 26 '15 at 06:15
  • As an example, ImportString["1.234 5.678e2", "Table"] might do the sort of thing that you want. – Stephen Luttrell Jan 26 '15 at 10:21

2 Answers2

4

This is a good question, but unfortunately there doesn't seem to be a perfect solution.

  1. 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)

  2. 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 checking

  3. In version 10, there's Interpreter. For example, Interpreter["Number"]["1.24"]. It is flexible, supports both 1.23e4 and 1.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.

Szabolcs
  • 234,956
  • 30
  • 623
  • 1,263
  • 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. – Sjoerd C. de Vries Apr 01 '15 at 07:44
1

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
Christopher Haydock
  • 1,215
  • 8
  • 12