-
Notifications
You must be signed in to change notification settings - Fork 6
/
Math.jack
executable file
·141 lines (118 loc) · 3.49 KB
/
Math.jack
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
// This file is part of www.nand2tetris.org
// and the book "The Elements of Computing Systems"
// by Nisan and Schocken, MIT Press.
// File name: projects/12/Math.jack
/**
* A library of commonly used mathematical functions.
* Note: Jack compilers implement multiplication and division using OS method calls.
*/
class Math {
static Array twoToThe;
/** Initializes the library. */
function void init() {
let twoToThe = Array.new(16);
let twoToThe[0] = 1;
let twoToThe[1] = 2;
let twoToThe[2] = 4;
let twoToThe[3] = 8;
let twoToThe[4] = 16;
let twoToThe[5] = 32;
let twoToThe[6] = 64;
let twoToThe[7] = 128;
let twoToThe[8] = 256;
let twoToThe[9] = 512;
let twoToThe[10] = 1024;
let twoToThe[11] = 2048;
let twoToThe[12] = 4096;
let twoToThe[13] = 8192;
let twoToThe[14] = 16384;
let twoToThe[15] = 16384 + 16384;
return;
}
/** Returns true if the i-th bit of x is 1, false otherwise. */
function boolean bit(int num, int index) {
return ~((num & twoToThe[index]) = 0);
}
/** Returns the absolute value of x. */
function int abs(int x) {
if (x < 0) {
return -x;
}
return x;
}
/** Returns the product of x and y.
* When a Jack compiler detects the multiplication operator '*' in the
* program's code, it handles it by invoking this method. In other words,
* the Jack expressions x*y and multiply(x,y) return the same value.
*/
function int multiply(int x, int y) {
var int sum, shiftedX, i;
let sum = 0;
let i = 0;
let shiftedX = x;
while (i < 16) {
if (Math.bit(y, i)) {
let sum = sum + shiftedX;
}
let shiftedX = shiftedX + shiftedX;
let i = i + 1;
}
return sum;
}
/** Returns the integer part of x/y.
* When a Jack compiler detects the multiplication operator '/' in the
* program's code, it handles it by invoking this method. In other words,
* the Jack expressions x/y and divide(x,y) return the same value.
*/
function int divide(int x, int y) {
var int q, result;
var boolean isPositive;
let isPositive = ((x < 0) = (y < 0));
let x = Math.abs(x);
let y = Math.abs(y);
if (x < y) {
return 0;
}
let q = Math.divide(x, 2 * y);
if ((x - (2 * q * y)) < y) {
let result = 2 * q;
} else {
let result = (2 * q) + 1;
}
if (isPositive) {
return result;
} else {
return -result;
}
}
/** Returns the integer part of the square root of x. */
function int sqrt(int x) {
var int y, j, power;
let y = 0;
let j = 7;
while ((j > 0) | (j = 0)) {
let power = (y + twoToThe[j]) * (y + twoToThe[j]);
if (((power < x) | (power = x)) & (power > 0)) {
let y = y + twoToThe[j];
}
let j = j - 1;
}
return y;
}
/** Returns the greater number. */
function int max(int a, int b) {
if (a > b) {
return a;
} else {
return b;
}
}
/** Returns the smaller number. */
function int min(int a, int b) {
if (a < b) {
return a;
} else {
return b;
}
}
}