3
$\begingroup$

Example: I have this number

num = 2.9525730420542016*10^1798
(* 2.952573042054202*10^1798 *)

If I want to convert it to a string, I don't get "2.952573042054202*10^1798" but

ToString[num, InputForm]
(* "2.9525730420542015686180548`15.954589770191005*^1798" *)

How to get

"2.952573042054202*10^1798"

as string back ?

To explain this question: I have a 1.5 GB file with several million such numbers. I need to do some recalculation and save it to a file again. However, if I save the resulting values (using Write [...]), a file more than twice the size will be created. The accuracy of the input numbers is about 17 digits, so the values in the new file cannot be more accurate. The other decimal places are meaningless, so I need to trim them.

$\endgroup$
8
  • $\begingroup$ You could take the logarithm and then store them in binary format, which would take only 8 bytes per number and avoid all such issues. I'm suggesting storing the logarithm because your number overflows the standard double-precision format. $\endgroup$ – Roman Jan 19 at 10:00
  • $\begingroup$ That's a good idea if I stayed inside Mathematica. But I need to have the output in text format so that it is easy to read in another program. $\endgroup$ – Vaclav Kotesovec Jan 19 at 10:04
  • $\begingroup$ Actually binary numbers can be read in any program, thanks to the IEEE 754 standard. $\endgroup$ – Roman Jan 19 at 10:11
  • 1
    $\begingroup$ Please stay with the original question. How to remove redundant digits from numbers obtained with N [...], resp. how to save really only in the specified accuracy, without extra digits? $\endgroup$ – Vaclav Kotesovec Jan 19 at 10:21
  • $\begingroup$ You might be interested in MantissaExponent[]. $\endgroup$ – J. M.'s ennui Jan 19 at 10:21
5
$\begingroup$

Are you satisfied with this form (without 10^)?

num = 2.9525730420542016*10^1798;

$NumberMarks = False; ToString[num, InputForm]

(*   2.9525730420542016*^1798   *)
$\endgroup$
2
  • $\begingroup$ This method is best! Thank you. $\endgroup$ – Vaclav Kotesovec Jan 19 at 21:45
  • $\begingroup$ Great! I don't even have to convert an array of real numbers to the strings. I can immediately write the whole array as N[array, 17] and nothing unnecessary will be saved. One magic word "$NumberMarks" is sufficient. $\endgroup$ – Vaclav Kotesovec Jan 19 at 22:27
5
$\begingroup$

The following function seems to do what you want

realToString[x_Real] := StringReplace[ToString[x,InputForm],
   StringExpression[a__~~"`"~~__~~"*^"~~b__]->a~~"*^"~~b];

For example try

FullForm[realToString@
     2.9525730420542015686180548`15.954589770191005*^1798]

which returns

"2.9525730420542015686180548*^1798"

If you want to limit the number of decimal digits then try

realToString[x_Real, nd_Integer:18] := Module[{a, b, ab=
  First[List@@StringReplace[ToString[x, InputForm],
  StringExpression[a__~~"`"~~__~~"*^"~~b__] -> {a ,b}]]},
  {a, b}=ab; StringTake[a, Min[StringLength@a, nd+1]]~~"*^"~~b];

For an example of this try

FullForm[realToString[
 2.9525730420542015686180548`15.954589770191005*^1798, 4]]

which returns

"2.952*^1798"

There are other ways to get Mathematica to do what you want, but this approach is more user programmable in my opinion.

$\endgroup$
2
  • $\begingroup$ This is usable, but there are still 8-9 digits left, which are not valid and unnecessarily increase the size of the output file. $\endgroup$ – Vaclav Kotesovec Jan 19 at 21:42
  • $\begingroup$ @VaclavKotesovec Thanks for your comment! I have upgraded my function which can now lmit the number of digits. $\endgroup$ – Somos Jan 19 at 22:21
2
$\begingroup$

Convert with CForm, apply ToString, then replace "e" with "*10^". We have:

num = 2.9525730420542016*10^1798;

CForm[num] displays "2.952573042054202e1798", and we can get a string with:

StringReplace["e"->"*10^"][ToString@CForm@num]

2.952573042054202*10^1798

For a list of values, make a list of strings with:

list = {num, num/1*^100, 2 num};
StringReplace["e"->"*10^"][ToString/@CForm/@list]

{2.952573042054202*10^1798, 2.952573042054202*10^1698, 5.905146084108403*10^1798}

$\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.