MathGroup Archive 2008

[Date Index] [Thread Index] [Author Index]

Search the Archive

Re: Is there a simple way to transform 1.1 to 11/10?

  • To: mathgroup at smc.vnet.net
  • Subject: [mg92974] Re: Is there a simple way to transform 1.1 to 11/10?
  • From: "Szabolcs HorvÃt" <szhorvat at gmail.com>
  • Date: Wed, 22 Oct 2008 05:35:21 -0400 (EDT)
  • References: <gdkajv$4r2$1@smc.vnet.net> <48FDBF08.5040207@gmail.com>

On Tue, Oct 21, 2008 at 14:49, Alain Cochard
<alain at geophysik.uni-muenchen.de> wrote:
> Szabolcs Horvat writes:
>  > Alain Cochard wrote:
>  > > The obvious
>  > >
>  > >     In[1]:= x=1.1`Infinity
>  > >
>  > > is not syntactically correct.
>  > >
>  > > I understand that SetPrecision[1.1,Infinity] does not work either:
>  > >
>  > >     In[3]:= SetPrecision[1.1,Infinity]
>  > >
>  > >             2476979795053773
>  > >     Out[3]= ----------------
>  > >             2251799813685248
>  > >
>  > >     In[4]:= N[%,20]
>  > >
>  > >     Out[4]= 1.1000000000000000888
>  > >
>  > > I searched the newsgroup and thought I had the solution with Rationalize:
>  > >
>  > >     In[5]:= Rationalize[1.1,0]
>  > >
>  > >             11
>  > >     Out[5]= --
>  > >             10
>  > >
>  > > But
>  > >
>  > >     In[9]:= Rationalize[1.000000001,0]
>  > >
>  > >             999999918
>  > >     Out[9]= ---------
>  > >             999999917
>  > >
>  > >     In[10]:= N[%,20]
>  > >
>  > >     Out[10]= 1.0000000010000000830
>  > >
>  > > So any simple way?
>  > >
>  >
>  > Hello Alain,
>  >
>  > Rationalize is the way to go.  Floating point numbers are usually stored
>  > in a binary (not decimal) representation on computers.  1.000000001 is
>  > not exactly representable in binary (in the same way as 1/3 =
>  > 0.3333333... is not exactly representable in decimal).  Note that in
>  > your example you start with a MachinePrecision number (approximately 15
>  > digits), and then convert back to a number with 20 digits of precision.
>  >   If you start with 1.000000001`20 then everything will be fine.
>  >
>  > In[1]:= Rationalize[1.000000001`20, 0]
>  > Out[1]= 1000000001/1000000000
>  >
>  > In[2]:= N[%, 20]
>  > Out[2]= 1.0000000010000000000
>  >
>  > Another example:
>  >
>  > In[1]:= Rationalize[N[Sqrt[2], 30], 0]
>  > Out[1]= 1023286908188737/723573111879672
>  >
>  > In[2]:= N[%, 30]
>  > Out[2]= 1.41421356237309504880168872421
>  >
>  > In[3]:= % - Sqrt[2]
>  > Out[3]= 0.*10^-30
>
> I don't really convert back to a number with 20 digits of precision.

You used N[%,20] in your example where % was the rationalization of a
MachinePrecision number.  If you convert it back to a MachinePrecision
number (simply N[%]), then you'll get the same number that you started
with, and not a different one.

> It was just to convince myself that it was not 1000000001/1000000000

Actually 1.000000001 isn't 1000000001/1000000000 either ... see below.

> The solution you give will not be fully general (as that by bob) since
> you have to adapt the '20' or the '30' for each case.  This is a bit
> painful for a given number and impossible to do in a program, it seems
> to me.
>

No, you misunderstood me.  I did not offer a solution.  I just tried
to explain why the result returned by Rationalize[1.000000001,0] is
correct, and why the "problem" does not exist at all.

You asked how you can transform 1.1 to 11/10.  This is not a precisely
defined question.  Why do you prefer 11/10?  Why not
1100000000000000088/1000000000000000000, for example?

In[1]:= SetPrecision[1.1, 20]
Out[1]= 1.1000000000000000888

The number 1.1 is not exactly 11/10 in Mathematica, for two reasons:

1.  It is represented in binary internally.  But this number is not
exactly representable in binary with a finite number of digits, and
Mathematica only uses only 53 binary digits by default (this is what
the hardware supports directly).

2. Mathematica always treats floating point numbers as inexact, and
keeps track of their precision.

The difference between 999999918/999999917 and 1000000001/1000000000
is so small that they cannot be differentiated when using machine
precision (which is less than 16 digits):

In[4]:= N[999999918/999999917 - 1000000001/1000000000]
Out[4]= 8.3*10^-17

In[5]:= N[999999918/999999917] == N[1000000001/1000000000]
Out[5]= True

What I meant was that you have to decide what precision to use.  If x
is defined up to e.g. 20 digits then x and Rationalize[x,0] will agree
up to 20 digits.


  • Prev by Date: Re: Is there a simple way to transform 1.1 to 11/10?
  • Next by Date: Re: Is there a simple way to transform 1.1 to 11/10?
  • Previous by thread: Re: Is there a simple way to transform 1.1 to 11/10?
  • Next by thread: Re: Is there a simple way to transform 1.1 to 11/10?