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.