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.

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?

share|improve this question
5  
Rationalize[0.123] –  Yi Wang Feb 11 at 19:25
3  
Rationalize does have limitations, though. –  Michael E2 Feb 11 at 19:51
    
@MichaelE2 Could you explain it a bit? –  Yi Wang Feb 11 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 at 21:51
2  
@YiWang You're welcome! :) Even Rationalize[0.333333333, 0] does not do what the OP wants. –  Michael E2 Feb 11 at 21:58

2 Answers 2

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.

share|improve this answer
    
How about $Pre = # /. r_Real :> RuleCondition[Round[r, 10^-Ceiling@Precision@r]] & –  Simon Woods Apr 15 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 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.

share|improve this answer
3  
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 at 23:31

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.