# How can I get these decimals formatted properly?

It's nothing serious, but I was just wondering. I have a large number of floating point numbers which I write to a file. Mathematica writes each number with 17 decimal positions, which is way more than I need, so I rounded to 3 decimal positions.

a = Table[RandomReal[], 3]
a >> test;
b = Round[a, 0.001]
b >>> test
FilePrint["test"]


The output:

{0.125839, 0.407141, 0.567724}

{0.126, 0.407, 0.568}

{0.12583870135502573, 0.40714089222862637, 0.5677236611829515}
{0.126, 0.40700000000000003, 0.5680000000000001}


What I see in my notebook is what I expect, what's written to the file is not (though I know where it comes from). Is there an easy way to get rid of the non-zero digit in the 17th decimal position, so that all numbers have the same length?

• Round won't help here (compare the outputs of e.g. [email protected] and FullForm@Round[0.072, 0.001]). Since you want to change display aspects, consider one of the *Form functions, in this case perhaps NumberForm[yourNumbers, 3. Jun 14, 2022 at 14:28
• Possible duplicate: stackoverflow.com/q/1089018 Jun 14, 2022 at 17:33
• @Roman - I don't think it is. I know that decimal numbers can't always be represented exact in binary. OP wasn't why this occurred, but rather how to get rid of it, more specifically in output. Thanks for your comment, anyway. Jun 14, 2022 at 17:40
• @MarcoB - I tried NumberForm[], but the function doesn't seem to work with PutAppend[], as it is a form of Print[]. Jun 14, 2022 at 17:57
• Be nice to have a random seed that reproduces this behavior. I don't really doubt it happens, but it hasn't happened my trials. So I can't help. Jun 14, 2022 at 22:44

I recommend using Export instead of Put/Get. I find that the latter are geared towards dealing with Wolfram Language expressions, rather than general input / output. As you mentioned, Put/PutAppend will export a NumberForm expression literally, rather than exporting its visual output.

Instead, collect the data to be exported in a variable, and then export them all at once with Export, formatting them as you wish. Here is an example:

Export[
"test",
{
0.81745,
Round[0.81745, 0.001],
ToString@NumberForm[Round[0.817, 0.001], 3]
},
"Text"
]


The contents of the test file then become:

0.81745
0.8170000000000001
0.817

• I just discovered the ToString[] solution myself :-). Thanks. About using Export, I write a header in the file before my data, so I'm put up (pun intended) with Put[] Jun 14, 2022 at 18:48

Since the output form is rounded to six digits, the last three being omitted since they are zero, this works:

a = RandomReal[1, 3];
a >> /tmp/test;
b = Round[a, 0.001];
OutputForm@b >>> /tmp/test;
FilePrint["/tmp/test"]


MarcoB's answer is almost there, but ToString[] add quotes around the list, which I don't want. I got rid of them by applying OutputForm[]:

OutputForm[ToString[NumberForm[a, 3]]] >>> test


The test notebook:

a=Table[RandomReal[], 3];
a >> test
Round[a, 0.001] >>> test
ToString[NumberForm[a, 3]] >>> test (* Marco's solution *)
OutputForm[ToString[NumberForm[a, 3]]] >>> test
FilePrint["test"]


and the output:

{0.4693043144910223, 0.35941460903748146, 0.4241708691371522}
{0.46900000000000003, 0.359, 0.424}
"{0.469, 0.359, 0.424}"
{0.469, 0.359, 0.424}


Edit
Note that while the last line looks like a list, it isn't, and we have to convert it again to an expression to use it as such:

a = OutputForm[ToString[NumberForm[RandomReal[1, 3], 3]]];
list = {x0, y0, x1, y1, a}
Flatten[list]  (* length is 5 *)
list = {x0, y0, x1, y1, ToExpression[ToString[a]]}
Flatten[list]  (* length is 7 *)


output:

{2513, 923, 2597, 931, {0.612, 0.687, 0.928}}
{2513, 923, 2597, 931, {0.612, 0.687, 0.928}}
{2513, 923, 2597, 931, {0.612, 0.687, 0.928}}
{2513, 923, 2597, 931, 0.612, 0.687, 0.928}