19
$\begingroup$

I'm trying to make a demonstration of how rounding to different numbers of digits affects things but I can't find a way to round numbers to a specified number of digits.

The Roundfunction only round to the nearest whole integer, and that is not what I always want. Other ways seems to only change the way the numbers are displayed, not how they are internally stored.

I want to throw away precision, but it seems Mathematica doesn't want to allow me to do this. As an example: I would like to round 3.4647 to just 3.5 or 3.46.

There must be some way to do this, but I can't for the life of me find it.

$\endgroup$
3
  • 7
    $\begingroup$ Round[x,a] rounds to the nearest multiple of a $\endgroup$
    – acl
    Jul 4, 2012 at 12:46
  • 3
    $\begingroup$ @acl Actually, that's not quite true: when a is a machine value, then after the rounding, the result has to be expressed in double precision binary, causing further rounding in the 52nd digit (base 2). Normally nobody would care, but if you're studying the effects of rounding and your investigation takes you into the realm of tiny changes and high precision, this effect could become important. $\endgroup$
    – whuber
    Jul 4, 2012 at 20:05
  • $\begingroup$ @whuber right, that was pasted from the docs. That is, I was pointing out that Round does what is being asked for, and this is mentioned at the top of the Round doc page. $\endgroup$
    – acl
    Jul 4, 2012 at 20:12

4 Answers 4

25
$\begingroup$

Just specify the nearest multiple in the second argument.

Round[123.456, 0.01]

123.46

$\endgroup$
5
  • 1
    $\begingroup$ Ah! Now I feel stupid. I did look at that but for some reason I assumed a had to be a whole number. $\endgroup$
    – Mr Alpha
    Jul 4, 2012 at 23:17
  • 2
    $\begingroup$ There are some problems with Round. For example, try Round[4.811] and you get 4.8100000000000005, not 4.81 as expected. $\endgroup$
    – Murta
    Nov 9, 2014 at 22:56
  • $\begingroup$ Nice observation. That also occurs with 481/100. but not with N[481/100] so the safer usage is to round to integer like N[Round[100*4.811]/100] $\endgroup$ Nov 9, 2014 at 23:19
  • 2
    $\begingroup$ @ChrisDegnen I'm using N@Round[100*4.811,1/100] to solve that. But take care with automatic Map compilation, details here: 65298 $\endgroup$
    – Murta
    Nov 10, 2014 at 13:21
  • $\begingroup$ Still have some stupid problems like Round[4.897, 0.01]=4.9 instead of 4.90. $\endgroup$
    – Xiaoyu Liu
    Jul 5 at 19:04
9
$\begingroup$

Suppose Round did not take a second argument as it does. What to do?

myround[n_, a_] := Round[n/a] a

myround[π, 0.001]

myround[π, 1/7]
3.142

22/7
$\endgroup$
3
  • 2
    $\begingroup$ Now, suppose Round didn't exist. round[num_] := Sign[num] (1 + Floor[Abs[num] - 0.5]) $\endgroup$
    – Rojo
    Jul 4, 2012 at 15:21
  • $\begingroup$ sign=Boole[# > 0] &, floor = IntegerPart[#] + (Sign[#] - 1)/2 &, integerPart = ToExpression@First@StringSplit[ToString@#, "."] & $\endgroup$
    – Rojo
    Jul 4, 2012 at 15:26
  • 5
    $\begingroup$ Now, if not even Boole existed, I would consider going checking out Maple or Matlab $\endgroup$
    – Rojo
    Jul 4, 2012 at 15:27
7
$\begingroup$
round1[x_, n_] := Ceiling[10^n x]/10^n // N
round2[x_, n_] := Floor[10^n x]/10^n // N
round1[3.4647, 1]
round2[3.4647, 2]
3.5
3.46
$\endgroup$
2
  • 2
    $\begingroup$ (+1) This is a good approach--provided you omit the // N at the ends of the functions! Because the OP wants to study the effects of rounding, they should take advantage of MMA's exact arithmetic to do their calculations. This will demonstrate that the internal rounding implicit in the conversion to double-precision floats is not affecting anything. Also, to really round, rather than truncate, you should add 1/2, as in Ceiling[10^n x + 1/2]/10^n. $\endgroup$
    – whuber
    Jul 4, 2012 at 20:07
  • $\begingroup$ @whuber Thanks for un upvote. I used //N to provide the number wanted by the OP, otherwise it would return a rational number. $\endgroup$
    – Artes
    Jul 5, 2012 at 19:29
0
$\begingroup$

Another solution is

Round1[x_, n_] := With[{m = Round[Log10[Abs[x]]]}, Round[x 10^(n - m)] 10.^(m - n)];

(*m estimates the scale of x, n sets the number precision, Abs function enables negative number.*)

Round1[-3.46473*10^-15, 4] // InputForm
(*-3.465*^-15*)
$\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.