# Fraction arithmetic practice sheet

The next logical step after yesterday’s worksheet for reducing fractions is one for adding and subtracting fractions.

The rules for using it are the same as my other math practice sheets:

• A new set of problems is generated every time you open or Refresh/Reload the page.
• You can use the version online or save a copy to your hard disk. A single file contains all the HTML, CSS, and JavaScript.
• The sheets are intended to be printed out and written on, as your child would do a set of homework problems.
• I don’t give answers; these are practice for you, too.
• Feel free to modify the code as you see fit, but please don’t delete the license and attribution information near the top of the file.

Here’s the code:

html:
1:  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
2:    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3:  <html>
4:  <!--
5:  A math practice sheet for adding and subtracting fractions.
6:  Released under the Creative Commons Attribution-Share Alike 3.0
8:  by Dr. Drang (http://www.leancrew.com).
9:  -->
11:      <title>Fraction Arithmetic</title>
12:      <style type="text/css">
13:        h1 {
14:          text-align: center;
15:          font-family: Sans-Serif;
16:          font-weight: bold;
17:          font-size: 36px;
18:          margin-top: 36px;
20:        }
21:        #whole {
22:          margin-left: auto;
23:          margin-right: auto;
24:        }
25:        table.problem {
26:          font-family: Sans-Serif;
27:          font-size: 24px;
28:          text-align: center;
29:          margin: 45px;
30:        }
31:        td.op {
32:          padding: 0 10px 0 10px;
33:
34:        }
35:        td.numerator {
36:          border-bottom: solid;
37:        }
38:      </style>
39:
40:      <script type="text/javascript">
41:      // GCD of two positive integers.
42:      function gcd(a, b) {
43:        if (b > a) {
44:          var temp = a; a = b; b = temp;
45:        }
46:        while (true) {
47:           a %= b;
48:           if (a == 0) return b;
49:           b %= a;
50:           if (b == 0) return a;
51:        }
52:        return b;
53:      }
54:
55:      // Return all numerators of reduced fractions with given denominator.
56:      function numerators(d) {
57:        var p = [];
58:        for (var i=1; i<d; i++) {
59:          p.push(i);
60:        }
61:        var n = p.filter(function(e, i, a) {
62:          return gcd(e, d) == 1;
63:        });
64:        return n;
65:      }
66:
67:      // Return all reduced fractions with denominators up through the
68:      // given value. Result will be a list of lists.
69:      function fractions(denoms) {
70:        f = [];
71:        for (var j=0; j<denoms.length; j++) {
72:          var n = numerators(denoms[j]);
73:          for (var i=0; i<n.length; i++) {
74:            f.push([n[i],denoms[j]]);
75:          }
76:        }
77:        return f;
78:      }
79:
80:      // Generate all the reduced fractions.
81:      var allReduced = fractions([2,3,4,5,6,8,9,10,12]);
82:
83:      // The HTML for a single problem.
84:      function singleProblem() {
85:        var ops = ['+', '&minus;'];
86:        var first = allReduced[Math.floor(Math.random()*allReduced.length)];
87:        var second = allReduced[Math.floor(Math.random()*allReduced.length)];
88:        var operator = ops[Math.floor(Math.random()*2)];
89:        // Switch the fractions if necessary to avoid negative answers.
90:        if (second[0]/second[1] > first[0]/first[1] && operator == '&minus;') {
91:          var temp = first; first = second; second = temp;
92:        }
93:        return '<table class="problem">' +
94:                '<tr><td class="numerator">' + first[0] + '</td>' +
95:                ' <td class="op" rowspan=2>' + operator + '</td>' +
96:                '<td class="numerator">' + second[0] + '</td>' +
97:                '<td class="op" rowspan=2>=</td>' +
98:                '<tr><td>' + first[1] + '</td><td>' + second[1] + '</td></tr>' +
99:                '</table>';
100:      }
101:
102:      </script>
104:    <body>
105:      <h1>Fraction Arithmetic</h1>
106:      <table id="whole">
107:          <script>
108:          for (i=0; i<5; i++){
109:            document.write("<tr>");
110:            for (j=0; j<3; j++) {
111:              document.write('<td>' + singleProblem() + '</td>');
112:            }
113:            document.write('</tr>');
114:          }
115:          </script>
116:      </table>
117:    </body>
118:  </html>


We’re reusing a lot of what we covered in yesterday’s post. The gcd, numerators, and fractions functions are unchanged. The singleProblem function (Lines 84-100) now generates two random fractions and an operator (equally likely to be plus or minus) and returns the HTML that formats them into an equation.

The population from which the fractions are chosen consists of all reduced proper fractions with denominators of 2, 3, 4, 5, 6, 8, 9, 10, or 12. The maximum denominator is 12 because I wanted the fractions to be relatively simple. Denominators of 7 and 11 aren’t included because they’re prime and don’t have multiples among the others—I wanted most of the problems to have common denominators that weren’t simply the product of the two given denominators.

Because the fractions are chosen randomly, most of the problems will require you to work out a common denominator, but some won’t. All the answers will be positive (see Lines 89-92). Some answers will be greater than one; it’s up to you to decide whether you want those answers given as improper fractions or mixed numbers. I do think all answers should be given in lowest terms, but that’s up to you, too.

I’ll probably create a fraction multiplication/division sheet in the next day or so. Because it’ll be almost exactly the same as this one, I won’t bother writing a post about it; I’ll just put a link to it below this paragraph and on the page with all my math practice sheets.

Update 1/7/11
The fraction multiplication and division sheet is here. The code is the same as above, but with Line 85 changed to

var ops = ['&times;', '&divide;'];


and Lines 89-92 removed because there’s no need to guard against negative answers.