5
$\begingroup$

I found a strange behavior in Round. If we try:

ToString[Round[4.811, 0.01], InputForm]

we get:

4.8100000000000005

When I expected

4.81

In order to get what I need, we can do something like (@Pickett and my suggestions):

N@FromDigits@RealDigits@Round[4.811, 0.01] 

or

Internal`StringToDouble@ToString@Round[4.811, 0.01]

There is a simpler solution for this?

Speed teste

range=Range[1,1000,0.01];
(t1=N@FromDigits@RealDigits@Round[#,0.01]&/@range)//AbsoluteTiming//First
(t2=Internal`StringToDouble@ToString@Round[#,0.01]&/@range)//AbsoluteTiming//First

0.999

0.460

Update

Important note. @BobHanlon solution stop to work for lists with more than 99 elements. Mathematica compiles de expression N@Round[#,1/100]&/@list, and the unwanted behavior came back. To prevent that, I used Listable Round attribute.

Similar question: Rounding problems inside InputField

$\endgroup$
2
  • $\begingroup$ Related: (7871), (55292), $\endgroup$
    – Mr.Wizard
    Commented Nov 10, 2014 at 13:13
  • 1
    $\begingroup$ This saved my day! Thank you, Murta $\endgroup$
    – matheorem
    Commented Mar 17, 2019 at 7:27

2 Answers 2

3
$\begingroup$

myround is undefined. I assume that you mean Round.

ToString[Round[4.811, 0.01]]

"4.81"

ToString[Round[4.811, .01 // Rationalize] // N, InputForm]

"4.81"

$\endgroup$
1
  • $\begingroup$ Yes, corrected myround to round. N@Round[4.811, 1/100] is much faster. tks +1 $\endgroup$
    – Murta
    Commented Nov 10, 2014 at 9:51
2
$\begingroup$

I suggest that you should be using a number formatting function, e.g. NumberForm, for the kind of control you are apparently after.

For Round and ToString only you could use OutputForm:

ToString[Round[4.811, 0.01], OutputForm]
"4.81"

Which is the default and therefore equivalent to this on an unmodified installation:

ToString @ Round[4.811, 0.01]

I am not sure how to interpret your comment but addressing one possible reading please consider:

a = Round[4.811, 0.01];
b = N @ FromDigits @ RealDigits @ Round[4.811, 0.01];

ToString[{a, b}, InputForm]

RealDigits[{a, b}]
"{4.8100000000000005, 4.81}"

{{{4, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 1},
 {{4, 8, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9}, 1}}

Although b happens to print as you desire you can see that its decimal conversion (with RealDigits) is not as "good" as the simple Round result. Neither number is accurate because you cannot represent 481/100 as a machine precision binary number:

RealDigits[481/100, 2]
{{1, 0, 0, 1, 1, {0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0}}, 3}

Therefore this is unlikely to be a desirable numeric operation, returning us again to the domain of output formatting. What exactly is your intention?

$\endgroup$
3
  • $\begingroup$ Tks @Mr.Wizard, but I need it as numbers. Now I'm using N@Round[4.811, 1/100]. I have some problems with automatic compilation, but now it's ok. OutputForm has problems with big numbers, and InputForm works just nice. $\endgroup$
    – Murta
    Commented Nov 10, 2014 at 13:18
  • $\begingroup$ @Murta Please see my addendum. $\endgroup$
    – Mr.Wizard
    Commented Nov 10, 2014 at 13:47
  • $\begingroup$ I use it to create a SQL insert statement, where numbers are rounded to prevent unnecessary file size. My insert get much more fast with this rounded "bulk" mechanist. I'll post a question/answer showing how it works, it's interesting to be shared. $\endgroup$
    – Murta
    Commented Nov 10, 2014 at 18:34

Your Answer

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

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