Re: Bug 1+4/10
- To: mathgroup at smc.vnet.net
- Subject: [mg120045] Re: Bug 1+4/10
- From: DrMajorBob <btreat1 at austin.rr.com>
- Date: Thu, 7 Jul 2011 07:28:46 -0400 (EDT)
- References: <201107060940.FAA29406@smc.vnet.net>
- Reply-to: drmajorbob at yahoo.com
1.4 is stored in a finite number of bits, despite the fact that its
expansion in binary is repeating:
{bits, digitsToLeft} = RealDigits[input = 1.4, 2];
{{1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1,
1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0,
0, 1, 1, 0, 0, 1, 1, 0}, 1}
The number stored (as opposed to the number written down) is
(conceptually):
stored = FromDigits[bits, 2]/2^(-digitsToLeft + Length@bits)
3152519739159347/2251799813685248
The stored number, as you see, is not precisely 1 + 4/10.
Set to various precisions and displayed, "stored" looks like this:
Table[{k, SetPrecision[stored, k]}, {k, 30}]
{{1, 1.}, {2, 1.4}, {3, 1.40}, {4, 1.400}, {5, 1.4000}, {6,
1.40000}, {7, 1.400000}, {8, 1.4000000}, {9, 1.40000000}, {10,
1.400000000}, {11, 1.4000000000}, {12, 1.40000000000}, {13,
1.400000000000}, {14, 1.4000000000000}, {15, 1.40000000000000}, {16,
1.400000000000000}, {17, 1.3999999999999999}, {18,
1.39999999999999991}, {19, 1.399999999999999911}, {20,
1.3999999999999999112}, {21, 1.39999999999999991118}, {22,
1.399999999999999911182}, {23, 1.3999999999999999111822}, {24,
1.39999999999999991118216}, {25, 1.399999999999999911182158}, {26,
1.3999999999999999111821580}, {27,
1.39999999999999991118215803}, {28,
1.399999999999999911182158030}, {29,
1.3999999999999999111821580300}, {30,
1.39999999999999991118215802999}}
As precision increases, the displayed number comes closer and closer to
the "stored" number, which is NOT necessarily closer to 1 + 4/10.
SetPrecision works with what it has, in other words... not with what
you're thinking. It treats the first argument as a calculated result, not
a raw textual input.
(The "stored" number above is a Rational, and is NOT used in Mathematica
calculations; computer arithmetic is used on a machine Real, with all its
attendant inaccuracies... and SPEED.)
A setPrecision function can be written to work with raw input, but you'd
have to feed it "1.4" as a String (or some such), since entering 1.4 alone
immediately results in a machine precision Real. That function would be no
use with calculated results, so we'd still need SetPrecision, as is, for
general purposes.
You already know how to input and use 1 + 4/10, which is stored as a
Rational:
1 + 1/4 // FullForm
Rational[5,4]
Here you can see the repeating binary digits mentioned earlier:
RealDigits[1 + 4/10, 2]
{{1, {0, 1, 1, 0}}, 1}
Bottom line? Rationals are exact. Reals are not.
Get used to it!
Bobby
On Wed, 06 Jul 2011 04:40:16 -0500, slawek <slawek at host.pl> wrote:
> Let check
>
> In[1]:= 1.4 == 1 + 4/10
> Out[1]= True
>
> In[2]:= a = SetPrecision[1.4, 30]
> Out[2]= 1.39999999999999991118215802999
>
> In[3]:= b = SetPrecision[1 + 4/10, 30]
> Out[3]= 1.40000000000000000000000000000
>
> No comment is needed.
>
> slawek
>
>
--
DrMajorBob at yahoo.com
- References:
- Bug 1+4/10
- From: "slawek" <slawek@host.pl>
- Bug 1+4/10