0
$\begingroup$

My problem is simple. Consider the following.

a = {15, 15.01, 3, 3.01}
(* Out: {15, 15.01, 3, 3.01} *)

Mean[a]
(* Out: 9.005 *)

a - Mean[a]
(* Out: {5.995, 6.005, -6.005, -5.995} *)

Abs[a - Mean[a]]
(* Out: {5.995, 6.005, 6.005, 5.995} *)

Round[%, 0.01] 
(* Out: {6., 6.01, 6., 5.99} *)

As you can see, the values returned by Round[6.005, 0.01] vary: either $6.01$ or $6$ where the argument list shows $6.005$. The case where the argument list shows $5.995$ has a similar problem. I expected {6., 6.01, 6.01, 6.}.

Why does this occur, and how can I get a right answer?

Update

I misunderstood belisarius’ comment. He has explained why.

I thank to MacroB for his answer.

However, the question concerning how to get the result I expected is not yet answered.

$\endgroup$
  • 2
    $\begingroup$ try Abs[a - Mean[a]] // FullForm and you'll see ... $\endgroup$ – Dr. belisarius Aug 18 '15 at 14:05
  • $\begingroup$ do you still have a question? Note besides the floating point issue, Round rounds an exact .5 to the nearest even value, so the right answer one might expect mathematically here is {6.,6.,6.,6.} $\endgroup$ – george2079 Aug 18 '15 at 17:19
3
$\begingroup$

FullForm seems to be working fine here. Here is what belisarius alluded to in his comment, using your definitions and either InputForm, or FullForm as he suggested:

InputForm@Abs[a - Mean[a]]
FullForm@Abs[a - Mean[a]]

(* Out from InputForm:
{5.995000000000001, 6.005000000000001, 6.004999999999999, 5.994999999999999}

Out from FullForm:
List[5.995000000000001`,6.005000000000001`,6.004999999999999`,5.994999999999999`]
*)

As you can see, the first and last numbers are in fact different in a subtle way, and they will end up being rounded differently by Round.

$\endgroup$
3
$\begingroup$

The answer to the second part of your question is that you need to abandon machine precision arithmetic.

Perhaps the best way to proceed is use Mathematica's exact arithmetic.

a = Rationalize @ {15., 15.01, 3., 3.01}
Round[Abs[a - Mean[a]], 1/100]
{6, 6, 6, 6}

You could also use Mathematica's slower but more accurate arbitrary precision arithmetic.

a = {15.`25, 15.01`25, 3.`25, 3.01`25};
Round[Abs[a - Mean[a]], 0.01`22]
{6.000000000000000000000, 6.000000000000000000000, 
 6.000000000000000000000, 6.000000000000000000000

If you are wondering why all the numbers get rounded to 6, it is because of the even-odd rule -- rounding down occurs when 5000... is to the right of an even digit and rounding up occurs when it to the right of an odd one; e.g.,

Round[{5.5, 6.5}]
{6, 6}
$\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.