4
$\begingroup$

I want to import list from a file and I am using ReadList but my data is in format like this 8.2457409790900004e+08 but it i being imported like $8.24574*10^8$. Is there a way to increase the precision of import? Or even better, is there a way to change the notebook's precision globally ?

$\endgroup$
  • $\begingroup$ @MichaelE2 doing FullForm[number]gives me $8.24574098106`*^8$ which is still not 8.2457409810599995e+08, I would need 22 digits. $\endgroup$ – jason Sep 1 '14 at 10:42
  • 2
    $\begingroup$ I think the 22 digit requirement is worth putting in the question. $\endgroup$ – Michael E2 Sep 1 '14 at 10:43
  • 2
    $\begingroup$ Related, perhaps duplicate: (33498), (38952). I'm too tired to answer now; if no one else does in the next day remind me and I shall. $\endgroup$ – Mr.Wizard Sep 1 '14 at 11:20
  • 1
    $\begingroup$ @Mr.Wizard, It is finally solved thank you for help, I also your comments in other posts and also in those that you suggested it helped a lot. Finally this code worked :) ToExpression /@StringReplace[StringReplace[ReadList["Filename", String],"e" -> "0e"], "e" | "E" :> "*^"] $\endgroup$ – jason Sep 1 '14 at 13:10
  • 2
    $\begingroup$ According to IEEE 754 2008, §5.12.2, the standard character representation of "binary64" reals (double-precision reals) is 17 digits. No doubt Mathematica interprets your input that way. It seems likely that the data was written that way, too, unless you have some reason to think differently. $\endgroup$ – Michael E2 Sep 1 '14 at 14:36
3
$\begingroup$

You need to have sufficient precision in your input file to trigger an arbitrary precision representation automatically. In your example, you just need one more digit as, I believe, one digit past machine doesn't typically do it.

ImportString[
  "8.24574097909000040e+08,8.2457409790900004e+08",
  "CSV"]

(* Out: {{8.2457409790900004*10^8, 8.24574*10^8}} *)

There's no way to expect this to have 22 digits of precision since you don't have that much in your input. You can always call SetPrecision on the result.

$\endgroup$
  • $\begingroup$ I can import it as String that is no problem but then again converting the string to Number shows the same problem. In the end I want this value $8.2457409790900004e+08$ but Mathematica is only giving me $8.24574098106‘∗^8$ $\endgroup$ – jason Sep 1 '14 at 11:38
  • $\begingroup$ @jason There is no import as string in my example. I used ImportString since it works exactly as Import but allows one to show a whole example without reference to an internal file. If you want that specific number, then that specific number will need one more zero in your input file. Keep in mind also that you should get the binary number with the specified precision closest to your input, so that trailing digits are often present. I can't verify your 8.24574098106 as I get 8.24574097909*^8, which seems quite right. $\endgroup$ – Mark McClure Sep 1 '14 at 12:03
  • $\begingroup$ yeah I mean, I get the same 8.24574097909*^8 but I miss out on remaining 5 digits 00004 in the end. And it is important to get that too. Is there other ways then adding 0 at the end as the file is quite large. $\endgroup$ – jason Sep 1 '14 at 12:07
  • $\begingroup$ @jason You can use StringReplace: ImportString[StringReplace[ReadString[filename], "e" -> "0e"]] with an appropriate format for ImportString. $\endgroup$ – Michael E2 Sep 1 '14 at 12:25
  • $\begingroup$ @MichaelE2 and @Mark McClure I got it Finally thank you. I did like this ToExpression /@StringReplace[StringReplace[ReadList["Filename", String],"e" -> "0e"], "e" | "E" :> "*^"] and it worked with charm. :) But still can you tell me why was it neccessary to add 0 at the end? $\endgroup$ – jason Sep 1 '14 at 13:07
0
$\begingroup$

Note that the trick of adding a zero only works for numbers in scientific notation:

This is a convoluted approach that works with arbitrary floats:

 toarbprecision[string_] := 
     Module[{dp, ep, firstnonzero, mend, pow, dig},
       dp = StringPosition[string, "."][[1, 1]];
       ep = StringPosition[string, "e" | "E"];
       firstnonzero = StringPosition[string, ToString /@ Range[9]][[1, 1]];
       If[ep == {},
         mend = 0; pow = 0,
         mend =  ep[[1, 1]] ;
         pow = ToExpression[ StringTake[string, {mend + 1, -1}]]];
       (* optional to avoid creating arbitrary
              precision representation of low precision numbers
         If[mend-firstnonzero-1<=Round@$MachinePrecision,
            Return[ToExpression@string]];
       *)
       N[FromDigits[{#, 
             dp - firstnonzero + Boole[dp < firstnonzero] + pow}], Length@#] &@
         ToExpression@
          Cases[Characters[StringTake[string, {firstnonzero, mend - 1}]], 
             s_String /; (s != ".")]]

Example:

 v = N[10^6 Pi, 18];
 Export[ "test.csv", {v, N[v, 17], N[v, $MachinePrecision]}];
 FilePrint["test.csv"]
3.14159265358979324e6
3.1415926535897932e6
3.141592653589793e6
 in = (toarbprecision /@ ReadList[ StringToStream@#, Word,WordSeparators -> {","}]&
   /@ Import["test.csv", {"Text", "Lines"}])

{{3.14159265358979324*10^6}, {3.1415926535897932*10^6}, {3.141592653589793*10^6}}

 Precision /@ in

{18., 17., 16.}

Warning I just whipped this up quickly - I'd advise some considerable validation checking before putting it to real use

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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