# Enter exact rational numbers easily with decimal notation

Is there a simple way to enter decimal numbers such as 0.123 so that Mathematica interprets it as an exact rational number 123/1000?

-
Rationalize[0.123] – Yi Wang Feb 11 '14 at 19:25
Rationalize does have limitations, though. – Michael E2 Feb 11 '14 at 19:51
@MichaelE2 Could you explain it a bit? – Yi Wang Feb 11 '14 at 21:34
@YiWang Rationalize[0.333333], Rationalize[0.3333333333333], and the explanation in the docs: "Rationalize[x] yields x unchanged if there is no rational number close enough to x to satisfy the condition |p/q-x| < c/q^2, with c chosen to be 10^-4." – Michael E2 Feb 11 '14 at 21:51
@YiWang You're welcome! :) Even Rationalize[0.333333333, 0] does not do what the OP wants. – Michael E2 Feb 11 '14 at 21:58

No doubt this needs work to make robust:

 fract[s_String] := (
pow = StringLength[s] - First@First@StringPosition[s, "."];
ToExpression[StringReplace[s, "." -> ""]]/10^pow)

$PreRead = If[Head[#] =!= Real, ( # /. s_String :> StringReplace[s, a : ("." ~~ DigitCharacter ...) ~~ "*^" :> a <> " 10^"] /. s_String :> StringReplace[s, a : ( (DigitCharacter .. ~~ "." ~~ DigitCharacter ...) | (DigitCharacter ... ~~ "." ~~ DigitCharacter ..) ) :> "fract[\"" <> a <> "\"]"] ), #, #] & (1.23 + .1*^4 x) /Sin[ .5 a ]  (123/100 + 1000 x) Csc[a/2] Two known issues: this breaks if you use explicit precision backtic notation, or if your input contains floats within strings. - How about $Pre = # /. r_Real :> RuleCondition[Round[r, 10^-Ceiling@Precision@r]] & – Simon Woods Apr 15 '14 at 16:06
The point is to work with the actual text entered to avoid some of the issues raised in the comments arising from conversion to/from machine precision. (As a practical matter those issues may not be important, and using \$Pre like that is clearly cleaner and more robust ) – george2079 Apr 15 '14 at 16:57

Given the limitations described in the comments, a possibility is to use Ratiolize[x,0] in combination with SetPrecision or SetAccuracy. E.g.:

Rationalize[SetPrecision[0.33333, 5], 0]


1/3

While

Rationalize[SetAccuracy[0.3333, 5], 0] (* one less 3 *)


3332 / 9997

The point is to set Accuracy or Precision to the number of digits that would be normally entered to represent (conventionally) the desired rational as a floating point number.

-
I think the OP wants the outputs to be 33333/100000 and 3333/10000 respectively, but I think the simplest way to enter these numbers is 33333*^-5 and 3333*^-4, or as fractions. – Michael E2 Feb 11 '14 at 23:31