# Formatting a fraction as a mixed number

Is there a command that will take a rational number and rewrite it in a mixed-number-like form? That is, I'd like to apply a command to something like 10/7 and get the result 1 + 3/7 (or 3/7 + 1 would be fine, too). With polynomial division, the Apart[] command does the trick pretty well, but I haven't been able to find anything comparable for numbers.

-

Here is a definition for mixedForm that works for all cases, i.e. proper and improper fractions and integers.

Clear[mixedForm]
mixedForm[Rational[x_, y_]] :=
If[Abs@x > y, HoldForm[#1 + #2/y], x/y] & @@ (Sign@x QuotientRemainder[Abs@x, y])
mixedForm[x_Integer] := x


Some examples:

mixedForm /@ {2, 4/5, 10/3, -3/4, -5/2}
Out[1]= {2, 4/5, 3 + 1/3, -3/4, -2 - 1/2}


Compare with Eli's, which produces 0s if the number is an integer or a proper fraction

ImproperForm /@ {2, 4/5, 10/3, -3/4, -5/2}
Out[2]= {2 + 0, 0 + 4/5, 3 + 1/3, -1 + 1/4, -3 + 1/2}

-
+1 Mine had the same problem. –  Mr.Wizard Mar 22 '12 at 17:42
Yeah, I think yours is better. –  Eli Lansey Mar 22 '12 at 17:45
Nice... But, if -3/4 is -3/4, shouldn't -5/2 be -2-1/2? –  Rojo Mar 22 '12 at 18:36
@Rojo This no longer makes problems if we use FractionalPart and IntegerPart instead of QuotientRemainder. Look at my approach. –  Artes Mar 22 '12 at 18:41
@Rojo Thanks for catching that. This is easily fixed — see edit :) –  rm -rf Mar 22 '12 at 19:42

Another solution based on FractionalPart and IntegerPart would be :

Fraction[x_Rational]:=
Function[{z, y}, If[z!=0, HoldForm[z + y], HoldForm[y]],
{HoldAll}] @@ {IntegerPart[x], FractionalPart[x]}

Fraction[x_Integer] := x


This approach produces slightly different results than R.M.'s solution :

Fraction /@ {2, 4/5, 10/3, -3/4, -5/2}

{2, 4/5, 3 + 1/3, -3/4, -2 -1/2 }

-
True, +1... I'm taking it –  Rojo Mar 22 '12 at 18:45
@Rojo Thanks for an upvote ! –  Artes Mar 22 '12 at 18:58

Using the function from the notebook here:

ImproperForm[x_] :=
Function[{z, y}, HoldForm[z + y], {HoldAll}] @@ {Floor[x],x - Floor[x]}


Usage:

In[12]:= ImproperForm[10/7]
Out[12]= 1+3/7

-

This should work with any real, rationalizing it (so, it becomes an approximate result)... The integer part of a negative number is considered the floor of the number. I'm not sure what's desired in those cases...

ClearAll[MixedForm];

Format[MixedForm[r_?NumericQ]] := Module[{rat =
If[Element[r, Rationals], r,Rationalize[N@r, 0]], x, y},
{x, y} = Through@{Numerator, Denominator}[rat];
With[{num = x, den = y},
With[{quot = Quotient[num, den], rem = Mod[num, den]},
Defer[quot] + Defer[rem/den] /. Defer[_?PossibleZeroQ] -> 0]]];

MixedForm /: (h_Symbol /; MemberQ[Attributes[h], NumericFunction])[
bef___, MixedForm[stuff_], aft___] := MixedForm@h[bef, stuff, aft];

SetAttributes[MixedForm, {Listable, Flat}];

Unprotect[$OutputForms]; AppendTo[$OutputForms, MixedForm];
Protect[\$OutputForms];


Ok, first, we test it

MixedForm /@ {2, 4/5, 10/3, -3/4, -5/2}

{2, 4/5, 3 + 1/3, -1 + 1/4, -3 + 1/2}


Works as expected, if you expected the integer part to be the floor (which I don't think it's the most natural thing but I'm not sure)

We see that the function can also take machine precision numbers

MixedForm /@ {2., 0.8, 3.333333333333333, -0.75, -2.5}


gives the same result.

For consistency with built-ins, the retuned cell has the label with //MixedForm prepended. Unlike some of the other options based on HoldForm, you can copy the result and do arithmetics with it... You can also do some arithmetics with the returned values

{2, 4/5, 10/3, -3/4, -5/2} // MixedForm

{2, 4/5, 3 + 1/3, -1 + 1/4, -3 + 1/2}

% + 9

{11, 9 + 4/5, 12 + 1/3, 8 + 1/4, 6 + 1/2}


EDIT

Added the Listable and Flat attribute and changed the previous definition to only match numeric values. Now we don't need to map it

{2, 4/5, 10/3, -3/4, -5/2} // MixedForm


returns what's expected... But we lose the label in these cases

-
Could you give some examples of use and what you see as the strengths of this method? –  Mr.Wizard Mar 22 '12 at 18:57
@Mr.Wizard, sorry, wrong edit, now –  Rojo Mar 22 '12 at 19:12
This has the same error that you pointed out in mine ;) Also, you probably don't want to make the claim — "This should work with any real, rationalizing it...". I'd like to see a rationalized result for MixedForm[Sqrt[2]] :D Nevertheless, I voted for it :) –  rm -rf Mar 22 '12 at 20:27
Hehe, thanks for pointing out the Sqrt[2], the idea was for it to be approximate in those cases so I should change it to Rationalize[N@r, 0] for non rationals. Actually I got lost multitasking and I don't like my function much, I'd redo it... But it doesn't have that inconsistency I pointed out in yours, it just consistently chooses perhaps the "wrong" option, hehe. Thanks for the +1 –  Rojo Mar 22 '12 at 20:58

Here is an attempt to implement both formatting for entire expressions and basic arithmetic.

EDIT: fixed according to Artes' solution.

ClearAll[mixedForm]
Format[mixedForm[x : Except[_Rational]]] := x /. q_Rational :> mixedForm[q]
Format[mixedForm[q_Rational]] ^:= Interpretation[
If[Abs[q] < 1, q, HoldForm[# + #2] & @@ {IntegerPart@q, FractionalPart@q}],
q
]

mixedForm[q_] + (mixedForm[x_] | x_) ^:= mixedForm[q + x]
mixedForm[q_] * (mixedForm[x_] | x_) ^:= mixedForm[q * x]
mixedForm[q_] ^ (mixedForm[x_] | x_) ^:= mixedForm[q ^ x]


Now:

ff[2, 4/5, 10/3, gg[-3/4, -5/2]] // mixedForm
(* Out[1]= ff[2, 4/5, 3 + 1/3, gg[-(3/4), -2 - 1/2]] *)

x = mixedForm[8/3];
y = mixedForm[9/5];
x + y
(* Out[2]= 4 + 7/15 *)

x + 1/2
(* Out[3]= 3 + 1/6 *)

-
I knew you wouldn't have just given up –  Rojo Mar 22 '12 at 18:51
@Rojo I'm trying to take my own advice. (Again to the OP, I am not saying this is a low quality question, only that I am trying to respond with more than the most basic answer.) –  Mr.Wizard Mar 22 '12 at 18:53
What about something like mixedForm /: h_[bef___, mixedForm[stuff_], aft___] := h[bef, stuff, aft] for the arithmetic? –  Rojo Mar 22 '12 at 18:54
@Rojo have you tried that? –  Mr.Wizard Mar 22 '12 at 18:59
+1, for an entirely usable solution. –  rcollyer Mar 22 '12 at 19:59

I am using this function to make up problems for middle schoolers. They are used to writing mixed numbers without the sign between the integer part and fraction parts.

This version prints mixed numbers as middle schoolers expect them:

mF[Rational[x_, y_]] :=
If[Abs@x > y, Sign@x HoldForm[#1] HoldForm[#2/y], x/y] & @@ (Abs@QuotientRemainder[x, y]);
mF[x_Integer] := x;
`
-