Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

A (maybe noob) question: Let

a = 1234567891234567889998.5
b = 1234567891234567889999.5

Mathematica (v8) yields for

a*0.5 - b*0.5

--> 0. (wrong answer) and

(a - b)*0.5

--> -0.5 (correct answer)

although both expressions a*0.5 - b*0.5 and (a - b)*0.5 are mathematically identical. I set $MinPrecision = 200, to no avail.

Is there a way to get for both analytically identical expressions the same numerical result? In my original mathematical problem I want to compare two representations of the same problem, with one yielding a vast sum over products of binomial coefficients (yielding numerically results of order 10^2^n, for n > 10) with tiny numbers (order 0.1^2^n). Analytically I cannot simplify the expressions.

Thanks a bunch.

Michelle

share|improve this question
1  
By using 0.5, you lose the advantages of arbitrary precision, since 0.5 is a machine precision number. Why not divide the quantities by 2 instead? –  J. M. Jun 4 '13 at 15:33
5  
Actually 0. is not a wrong answer. Welcome to numerics. –  Daniel Lichtblau Jun 4 '13 at 15:50
    
@MichelleRudolph Welcome to Mma.SE! I've formatted the code in your post. You can look at what I did (and fix anything). In the toolbar above the editing window, there is a button to format selected text. Or you can use backticks for inline code and indent 4 spaces for code blocks. –  Michael E2 Jun 4 '13 at 15:55
    
I'm curious, where do numbers like 1234567891234567889998.5 come from? I mean, is it a real application? Or is it specifically a test of precision? –  Mark McClure Jun 4 '13 at 15:57
3  
The classic example of this is entering 1E12 + 1 - 1E12 on a ten digit calculator, and it can show up in unexpected ways in numerics. –  rcollyer Jun 4 '13 at 17:15
show 1 more comment

2 Answers 2

The problem is that the precision of a and b are set by the form of their input.

a = 1234567891234567889998.5; b = 1234567891234567889999.5;
Precision[a]
22.0915

And 0.5 by default has MachinePrecision, these days typically Log10[2^53] or just under 16 digits.

Precision[0.5]
MachinePrecision

Neither setting the precision of 0.5 to 200 or dividing by the exact number 2 fixes the precision of a or b:

a*0.5`200 - b*0.5`200
-0.*10^-1
a/2 - b/2
-0.*10^-1

Edit: I should probably point out that the funny output -0.*10^-1 means less than one digit of precision with the first nonzero digit in the tenths place.

a/2 - b/2 // FullForm
-0.5`0.6989700043360207

Set the precision to be as much more than b as needed or desired. Let's try one more digit.

extra = 1;
prec = Ceiling[Log10[1234567891234567889999.5]] + extra
23
a = SetPrecision[1234567891234567889998.5, prec];
b = SetPrecision[1234567891234567889999.5, prec];

a*SetPrecision[0.5, prec] - b*SetPrecision[0.5, prec]
Precision[%]
-0.5
1.30643

We see we end up with slight more than extra digits of precision.


Alternatively, you could enter a and b with explicit precision:

a = 1234567891234567889998.5`30;
b = 1234567891234567889999.5`30;

a * 0.5`30 - b * 0.5`30
-0.50000000
share|improve this answer
    
Thanks a great bunch, Michael. You detailed answer really helped! I appreciate very much! –  Michelle Rudolph Jun 4 '13 at 15:53
add comment

Arbitrary precision can be a tricky thing, particularly when you start to mix numbers at various levels of precision. As the was pointed out in the comments, if you mix quantities Mathematica will coerce the results to be of the lower precision. For example:

{Sin[Pi/4], Sin[0.25 Pi]}
(* Out: {1/Sqrt[2], 0.707107} *)

Note that Sin[Pi/4] returns the infinite precision number 1/Sqrt[2] while Sin[0.25Pi] returns the machine precision number $0.707107$. In your case, your mixing machine precision (the 0.5) with arbitrary precision (the long a and b). Let's check the intermediate expressions.

a = 1234567891234567889998.5;
b = 1234567891234567889999.5;
{a*0.5, b*0.5, a*0.5 - b*0.5, (a - b) 0.5}

(* Out: {6.17284*10^20, 6.17284*10^20, 0., -0.5} *)

Now you can see clearly what's happened.

Since I started typing, I notice that Michael E2 has already pointed out that (a-b)/2 yields a strange result due to the insufficient precision to express the result and also mentioned that SetPrecision can be used to improve the situation. Let me also mention a more compact way to enter this:

1234567891234567889998.5`30;
b = 1234567891234567889999.5`30;
(a - b)/2

(* Out: -0.50000000 *)

Have fun!!

share|improve this answer
    
Thanks Mark for the quick answer. All your suggestions helped very much. It's working now (my little test), and now on to solving the real problem (which gonna require some rewriting of my script along your suggestions). ;-) –  Michelle Rudolph Jun 4 '13 at 15:59
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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