8
$\begingroup$

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.

$\endgroup$
3
  • $\begingroup$ what is StringToDouble ? $\endgroup$ Commented Dec 17, 2013 at 7:19
  • 3
    $\begingroup$ @Nasser : mathematica.stackexchange.com/a/1744/121 $\endgroup$ Commented Dec 17, 2013 at 8:22
  • $\begingroup$ Related: (15051) $\endgroup$ Commented Mar 4, 2015 at 19:37

2 Answers 2

9
$\begingroup$

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.

$\endgroup$
11
  • $\begingroup$ 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. "' $\endgroup$ Commented Dec 17, 2013 at 10:01
  • $\begingroup$ @LCFactorization Please, what code causes that error? $\endgroup$ Commented Dec 17, 2013 at 10:07
  • $\begingroup$ # &[ReadList[#, Number], Close@#]& @ StringToStream @ string will casue such error; others are OK. $\endgroup$ Commented Dec 17, 2013 at 11:25
  • $\begingroup$ @LCF With what input? (What is assigned to string?) Which version are you using? I have not yet seen the error you describe. $\endgroup$ Commented Dec 17, 2013 at 11:49
  • 1
    $\begingroup$ 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"]}). $\endgroup$ Commented Dec 19, 2013 at 11:48
4
$\begingroup$

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}} 
$\endgroup$
7
  • 1
    $\begingroup$ 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? $\endgroup$ Commented Dec 17, 2013 at 8:49
  • $\begingroup$ Though this answer works, I am curious why there is so such command as close the Stream... $\endgroup$ Commented Dec 17, 2013 at 8:49
  • 1
    $\begingroup$ @LCFactorization closing the stream is important; see my answer for simple code to do this. $\endgroup$ Commented Dec 17, 2013 at 8:50
  • $\begingroup$ And there is such error messsage : ToExpression::notstr: The format type InputForm is valid only for string input $\endgroup$ Commented Dec 17, 2013 at 9:02
  • 1
    $\begingroup$ @LCFactorization, your example shows a string input, am I missing something? $\endgroup$ Commented Dec 17, 2013 at 9:10

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.