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

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$ Dec 17, 2013 at 10:01
  • $\begingroup$ @LCFactorization Please, what code causes that error? $\endgroup$
    – Mr.Wizard
    Dec 17, 2013 at 10:07
  • $\begingroup$ # &[ReadList[#, Number], Close@#]& @ StringToStream @ string will casue such error; others are OK. $\endgroup$ 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$
    – Mr.Wizard
    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$ 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$
    – Mr.Wizard
    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$ Dec 17, 2013 at 8:49
  • 1
    $\begingroup$ @LCFactorization closing the stream is important; see my answer for simple code to do this. $\endgroup$
    – Mr.Wizard
    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$ Dec 17, 2013 at 9:02
  • 1
    $\begingroup$ @LCFactorization, your example shows a string input, am I missing something? $\endgroup$
    – RunnyKine
    Dec 17, 2013 at 9:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.