// 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 st; static int division_tmp, f; /** Initializes the library. */ function void init() { var int a; let st = Array.new(16); let st[0] = 1; while (a < 15){ let a = a + 1; let st[a] = st[a - 1] + st[a - 1]; } return; } /** 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, temp, y_comp, i, neg; let neg = ((x < 0) & (y > 0)) | ((x > 0) & (y < 0)); let x = Math.abs(x); let y = Math.abs(y); if (x < y){ let temp = x; let x = y; let y = temp; } if (y = 1){ if(neg){ return -x; } return x; } while((y_comp - 1) < (y - 1)){ if ((st[i] & y) > 0) { let sum = sum + x; let y_comp = y_comp + st[i]; } let x = x + x; let i = i + 1; } if(neg){ let sum = -sum; } 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, neg; if (f = 0){ let division_tmp = 0; let neg = ((x < 0) & (y > 0)) | ((x > 0) & (y < 0)); let x = Math.abs(x); let y = Math.abs(y); if (y = 0){ do Sys.error(3); } let f = 1; } if ((y > x) | (y < 0)){ return 0; } let q = divide(x, y + y); let f = 0; let q = Math.abs(q); if ((q & 1) = 1){ let division_tmp = division_tmp + y + y; } if (x - division_tmp < y){ if (neg){ return -(q + q); } return q + q; } else{ if (neg){ return -(q + q + 1); } return q + q + 1; } } /** Returns the integer part of the square root of x. */ function int sqrt(int x) { var int j, b, d, y; if (x < 0){ do Sys.error(4); } let j = 7; while (j > -1){ let d = y + st[j]; let b = d * d; if ((~(b > x)) & (b > 0)){ let y = d; } let j = j - 1; } return y; } /** Returns the greater number. */ function int max(int a, int b) { if (a > b){ return a; } return b; } /** Returns the smaller number. */ function int min(int a, int b) { if (a < b){ return a; } return b; } }