# How to convert a string of number into real numbers without precision loss

I searched and did not find similar answers which can resolve the 'no precision loss' issue. A sample string is:

"-5.100686209408900133332e+02 -1.294005398404007344443e+01 -2.59376479781563728887e+02 -1.3043629998334040122222e+02"


If I immediately convert them into real variable by ImportString or StringToDouble, then there will be precision loss, the resulted precision is only $MachinePrecision. How to convert them into real number which should have higher precision than $MachinePrecision.

• what is StringToDouble ? Commented Dec 17, 2013 at 7:19
• Commented Dec 17, 2013 at 8:22
• Related: (15051) Commented Mar 4, 2015 at 19:37

This question feels familiar but I could not find a true duplicate.

You can use the string replacement that Oleksandr proposed here and then use ToExpression to convert the numbers:

string = "-5.100686209408900133332e+02 -1.294005398404007344443e+01 \
-2.59376479781563728887e-02 -1.3043629998334040122222e+02"

ToExpression /@ StringReplace[StringSplit@string, "e" | "E" :> "*^"]

{-510.068620940890013333, -12.94005398404007344443, -0.025937647978156372889,
-130.43629998334040122222}


Edit: a bug in verison 9 prevents the following solution from working.

Better I think, avoiding accidential code evaluation from ToExpression, you can use Read or ReadList with type Number, as I proposed for How do you convert a string containing a number in C scientific notation to a Mathematica number?:

# &[ReadList[#, Number], Close@#]& @ StringToStream @ string

{-510.068620940890013333, -12.94005398404007344443, -0.025937647978156372889,
-130.43629998334040122222}


Note that # &[body, cleanup] is simply a way to evaluate cleanup after body, then return body.

• However, the further command causes: error message: General::digit: "Digit at position 1 in \!(\"-5.100686209408900133332\") is too large to be used in base 10. "' Commented Dec 17, 2013 at 10:01
• @LCFactorization Please, what code causes that error? Commented Dec 17, 2013 at 10:07
• # &[ReadList[#, Number], Close@#]& @ StringToStream @ string will casue such error; others are OK. Commented Dec 17, 2013 at 11:25
• @LCF With what input? (What is assigned to string?) Which version are you using? I have not yet seen the error you describe. Commented Dec 17, 2013 at 11:49
• Yes, this is a version difference. It stops working in version 9. I suspect a bug since the errors do not make sense and a very strange output is produced ({100*Removed["$$Failure"], 10*Removed["$$Failure"], Removed["$$Failure"]/100, 100*Removed["$$Failure"]}). Commented Dec 19, 2013 at 11:48

The following is a place to start: Use StringToStream to convert the string data to an input stream:

num = "-5.100686209408900133332e+02 -1.294005398404007344443e+01
-2.59376479781563728887e+02 -1.3043629998334040122222e+02"


Now

str = StringToStream[num];


Use ReadList to read the InputStream

data = ReadList[str, Table[Record, {4}], RecordSeparators -> {" "}]; Close[str];


Here's the main trick to get your high precision Real

ReleaseHold[ToExpression[data, InputForm, Hold] /. {Plus[Times[x_, E | e], y_] :> x*10^y}]


Which gives:

{{-510.068620940890013333, -12.94005398404007344443, -259.37647978156372889,
-130.43629998334040122222}}

• I believe that there are simpler alternatives to this, as shown in my answer. Can you give any reason to use this more elaborate method? Commented Dec 17, 2013 at 8:49
• Though this answer works, I am curious why there is so such command as close` the Stream... Commented Dec 17, 2013 at 8:49
• @LCFactorization closing the stream is important; see my answer for simple code to do this. Commented Dec 17, 2013 at 8:50
• And there is such error messsage : ToExpression::notstr: The format type InputForm is valid only for string input Commented Dec 17, 2013 at 9:02
• @LCFactorization, your example shows a string input, am I missing something? Commented Dec 17, 2013 at 9:10